//===-- include/flang/Semantics/symbol.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_SYMBOL_H_
#define FORTRAN_SEMANTICS_SYMBOL_H_

#include "type.h"
#include "flang/Common/Fortran.h"
#include "flang/Common/enum-set.h"
#include "flang/Common/reference.h"
#include "llvm/ADT/DenseMapInfo.h"
#include <array>
#include <functional>
#include <list>
#include <optional>
#include <set>
#include <vector>

namespace llvm {
class raw_ostream;
}

namespace Fortran::semantics {

/// A Symbol consists of common information (name, owner, and attributes)
/// and details information specific to the kind of symbol, represented by the
/// *Details classes.

class Scope;
class Symbol;
class ProgramTree;

using SymbolRef = common::Reference<const Symbol>;
using SymbolVector = std::vector<SymbolRef>;
using MutableSymbolRef = common::Reference<Symbol>;
using MutableSymbolVector = std::vector<MutableSymbolRef>;

// A module or submodule.
class ModuleDetails {
public:
  ModuleDetails(bool isSubmodule = false) : isSubmodule_{isSubmodule} {}
  bool isSubmodule() const { return isSubmodule_; }
  const Scope *scope() const { return scope_; }
  const Scope *ancestor() const; // for submodule; nullptr for module
  const Scope *parent() const; // for submodule; nullptr for module
  void set_scope(const Scope *);

private:
  bool isSubmodule_;
  const Scope *scope_{nullptr};
};

class MainProgramDetails {
public:
private:
};

class WithBindName {
public:
  const std::string *bindName() const {
    return bindName_ ? &*bindName_ : nullptr;
  }
  void set_bindName(std::string &&name) { bindName_ = std::move(name); }

private:
  std::optional<std::string> bindName_;
};

class SubprogramDetails : public WithBindName {
public:
  bool isFunction() const { return result_ != nullptr; }
  bool isInterface() const { return isInterface_; }
  void set_isInterface(bool value = true) { isInterface_ = value; }
  bool isDummy() const { return isDummy_; }
  void set_isDummy(bool value = true) { isDummy_ = value; }
  Scope *entryScope() { return entryScope_; }
  const Scope *entryScope() const { return entryScope_; }
  void set_entryScope(Scope &scope) { entryScope_ = &scope; }
  const Symbol &result() const {
    CHECK(isFunction());
    return *result_;
  }
  void set_result(Symbol &result) {
    CHECK(!result_);
    result_ = &result;
  }
  const std::vector<Symbol *> &dummyArgs() const { return dummyArgs_; }
  void add_dummyArg(Symbol &symbol) { dummyArgs_.push_back(&symbol); }
  void add_alternateReturn() { dummyArgs_.push_back(nullptr); }
  const MaybeExpr &stmtFunction() const { return stmtFunction_; }
  void set_stmtFunction(SomeExpr &&expr) { stmtFunction_ = std::move(expr); }

private:
  bool isInterface_{false}; // true if this represents an interface-body
  bool isDummy_{false}; // true when interface of dummy procedure
  std::vector<Symbol *> dummyArgs_; // nullptr -> alternate return indicator
  Symbol *result_{nullptr};
  Scope *entryScope_{nullptr}; // if ENTRY, points to subprogram's scope
  MaybeExpr stmtFunction_;
  friend llvm::raw_ostream &operator<<(
      llvm::raw_ostream &, const SubprogramDetails &);
};

// For SubprogramNameDetails, the kind indicates whether it is the name
// of a module subprogram or internal subprogram.
ENUM_CLASS(SubprogramKind, Module, Internal)

// Symbol with SubprogramNameDetails is created when we scan for module and
// internal procedure names, to record that there is a subprogram with this
// name. Later they are replaced by SubprogramDetails with dummy and result
// type information.
class SubprogramNameDetails {
public:
  SubprogramNameDetails(SubprogramKind kind, ProgramTree &node)
      : kind_{kind}, node_{node} {}
  SubprogramNameDetails() = delete;
  SubprogramKind kind() const { return kind_; }
  ProgramTree &node() const { return *node_; }

private:
  SubprogramKind kind_;
  common::Reference<ProgramTree> node_;
};

// A name from an entity-decl -- could be object or function.
class EntityDetails : public WithBindName {
public:
  explicit EntityDetails(bool isDummy = false) : isDummy_{isDummy} {}
  const DeclTypeSpec *type() const { return type_; }
  void set_type(const DeclTypeSpec &);
  void ReplaceType(const DeclTypeSpec &);
  bool isDummy() const { return isDummy_; }
  void set_isDummy(bool value = true) { isDummy_ = value; }
  bool isFuncResult() const { return isFuncResult_; }
  void set_funcResult(bool x) { isFuncResult_ = x; }

private:
  bool isDummy_{false};
  bool isFuncResult_{false};
  const DeclTypeSpec *type_{nullptr};
  friend llvm::raw_ostream &operator<<(
      llvm::raw_ostream &, const EntityDetails &);
};

// Symbol is associated with a name or expression in a SELECT TYPE or ASSOCIATE.
class AssocEntityDetails : public EntityDetails {
public:
  AssocEntityDetails() {}
  explicit AssocEntityDetails(SomeExpr &&expr) : expr_{std::move(expr)} {}
  AssocEntityDetails(const AssocEntityDetails &) = default;
  AssocEntityDetails(AssocEntityDetails &&) = default;
  AssocEntityDetails &operator=(const AssocEntityDetails &) = default;
  AssocEntityDetails &operator=(AssocEntityDetails &&) = default;
  const MaybeExpr &expr() const { return expr_; }
  void set_rank(int rank);
  std::optional<int> rank() const { return rank_; }

private:
  MaybeExpr expr_;
  std::optional<int> rank_;
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const AssocEntityDetails &);

// An entity known to be an object.
class ObjectEntityDetails : public EntityDetails {
public:
  explicit ObjectEntityDetails(EntityDetails &&);
  ObjectEntityDetails(const ObjectEntityDetails &) = default;
  ObjectEntityDetails &operator=(const ObjectEntityDetails &) = default;
  ObjectEntityDetails(bool isDummy = false) : EntityDetails(isDummy) {}
  MaybeExpr &init() { return init_; }
  const MaybeExpr &init() const { return init_; }
  void set_init(MaybeExpr &&expr) { init_ = std::move(expr); }
  ArraySpec &shape() { return shape_; }
  const ArraySpec &shape() const { return shape_; }
  ArraySpec &coshape() { return coshape_; }
  const ArraySpec &coshape() const { return coshape_; }
  void set_shape(const ArraySpec &);
  void set_coshape(const ArraySpec &);
  const Symbol *commonBlock() const { return commonBlock_; }
  void set_commonBlock(const Symbol &commonBlock) {
    commonBlock_ = &commonBlock;
  }
  bool IsArray() const { return !shape_.empty(); }
  bool IsCoarray() const { return !coshape_.empty(); }
  bool IsAssumedShape() const { return isDummy() && shape_.IsAssumedShape(); }
  bool IsDeferredShape() const {
    return !isDummy() && shape_.IsDeferredShape();
  }
  bool IsAssumedSize() const { return isDummy() && shape_.IsAssumedSize(); }
  bool IsAssumedRank() const { return isDummy() && shape_.IsAssumedRank(); }

private:
  MaybeExpr init_;
  ArraySpec shape_;
  ArraySpec coshape_;
  const Symbol *commonBlock_{nullptr}; // common block this object is in
  friend llvm::raw_ostream &operator<<(
      llvm::raw_ostream &, const ObjectEntityDetails &);
};

// Mixin for details with passed-object dummy argument.
// If a procedure pointer component or type-bound procedure does not have
// the NOPASS attribute on its symbol, then PASS is assumed; the name
// is optional; if it is missing, the first dummy argument of the procedure's
// interface is the passed-object dummy argument.
class WithPassArg {
public:
  std::optional<SourceName> passName() const { return passName_; }
  void set_passName(const SourceName &passName) { passName_ = passName; }

private:
  std::optional<SourceName> passName_;
};

// A procedure pointer, dummy procedure, or external procedure
class ProcEntityDetails : public EntityDetails, public WithPassArg {
public:
  ProcEntityDetails() = default;
  explicit ProcEntityDetails(EntityDetails &&d);

  const ProcInterface &interface() const { return interface_; }
  ProcInterface &interface() { return interface_; }
  void set_interface(const ProcInterface &interface) { interface_ = interface; }
  bool IsInterfaceSet() {
    return interface_.symbol() != nullptr || interface_.type() != nullptr;
  }
  inline bool HasExplicitInterface() const;

  // Be advised: !init().has_value() => uninitialized pointer,
  // while *init() == nullptr => explicit NULL() initialization.
  std::optional<const Symbol *> init() const { return init_; }
  void set_init(const Symbol &symbol) { init_ = &symbol; }
  void set_init(std::nullptr_t) { init_ = nullptr; }

private:
  ProcInterface interface_;
  std::optional<const Symbol *> init_;
  friend llvm::raw_ostream &operator<<(
      llvm::raw_ostream &, const ProcEntityDetails &);
};

// These derived type details represent the characteristics of a derived
// type definition that are shared by all instantiations of that type.
// The DerivedTypeSpec instances whose type symbols share these details
// each own a scope into which the components' symbols have been cloned
// and specialized for each distinct set of type parameter values.
class DerivedTypeDetails {
public:
  const std::list<SourceName> &paramNames() const { return paramNames_; }
  const SymbolVector &paramDecls() const { return paramDecls_; }
  bool sequence() const { return sequence_; }
  std::map<SourceName, SymbolRef> &finals() { return finals_; }
  const std::map<SourceName, SymbolRef> &finals() const { return finals_; }
  bool isForwardReferenced() const { return isForwardReferenced_; }
  void add_paramName(const SourceName &name) { paramNames_.push_back(name); }
  void add_paramDecl(const Symbol &symbol) { paramDecls_.push_back(symbol); }
  void add_component(const Symbol &);
  void set_sequence(bool x = true) { sequence_ = x; }
  void set_isForwardReferenced(bool value) { isForwardReferenced_ = value; }
  const std::list<SourceName> &componentNames() const {
    return componentNames_;
  }

  // If this derived type extends another, locate the parent component's symbol.
  const Symbol *GetParentComponent(const Scope &) const;

  std::optional<SourceName> GetParentComponentName() const {
    if (componentNames_.empty()) {
      return std::nullopt;
    } else {
      return componentNames_.front();
    }
  }

  const Symbol *GetFinalForRank(int) const;

private:
  // These are (1) the names of the derived type parameters in the order
  // in which they appear on the type definition statement(s), and (2) the
  // symbols that correspond to those names in the order in which their
  // declarations appear in the derived type definition(s).
  std::list<SourceName> paramNames_;
  SymbolVector paramDecls_;
  // These are the names of the derived type's components in component
  // order.  A parent component, if any, appears first in this list.
  std::list<SourceName> componentNames_;
  std::map<SourceName, SymbolRef> finals_; // FINAL :: subr
  bool sequence_{false};
  bool isForwardReferenced_{false};
  friend llvm::raw_ostream &operator<<(
      llvm::raw_ostream &, const DerivedTypeDetails &);
};

class ProcBindingDetails : public WithPassArg {
public:
  explicit ProcBindingDetails(const Symbol &symbol) : symbol_{symbol} {}
  const Symbol &symbol() const { return symbol_; }

private:
  SymbolRef symbol_; // procedure bound to; may be forward
};

class NamelistDetails {
public:
  const SymbolVector &objects() const { return objects_; }
  void add_object(const Symbol &object) { objects_.push_back(object); }
  void add_objects(const SymbolVector &objects) {
    objects_.insert(objects_.end(), objects.begin(), objects.end());
  }

private:
  SymbolVector objects_;
};

class CommonBlockDetails : public WithBindName {
public:
  MutableSymbolVector &objects() { return objects_; }
  const MutableSymbolVector &objects() const { return objects_; }
  void add_object(Symbol &object) { objects_.emplace_back(object); }
  std::size_t alignment() const { return alignment_; }
  void set_alignment(std::size_t alignment) { alignment_ = alignment; }

private:
  MutableSymbolVector objects_;
  std::size_t alignment_{0}; // required alignment in bytes
};

class MiscDetails {
public:
  ENUM_CLASS(Kind, None, ConstructName, ScopeName, PassName, ComplexPartRe,
      ComplexPartIm, KindParamInquiry, LenParamInquiry, SelectRankAssociateName,
      SelectTypeAssociateName, TypeBoundDefinedOp);
  MiscDetails(Kind kind) : kind_{kind} {}
  Kind kind() const { return kind_; }

private:
  Kind kind_;
};

class TypeParamDetails {
public:
  explicit TypeParamDetails(common::TypeParamAttr attr) : attr_{attr} {}
  TypeParamDetails(const TypeParamDetails &) = default;
  common::TypeParamAttr attr() const { return attr_; }
  MaybeIntExpr &init() { return init_; }
  const MaybeIntExpr &init() const { return init_; }
  void set_init(MaybeIntExpr &&expr) { init_ = std::move(expr); }
  const DeclTypeSpec *type() const { return type_; }
  void set_type(const DeclTypeSpec &);
  void ReplaceType(const DeclTypeSpec &);

private:
  common::TypeParamAttr attr_;
  MaybeIntExpr init_;
  const DeclTypeSpec *type_{nullptr};
};

// Record the USE of a symbol: location is where (USE statement or renaming);
// symbol is in the USEd module.
class UseDetails {
public:
  UseDetails(const SourceName &location, const Symbol &symbol)
      : location_{location}, symbol_{symbol} {}
  const SourceName &location() const { return location_; }
  const Symbol &symbol() const { return symbol_; }

private:
  SourceName location_;
  SymbolRef symbol_;
};

// A symbol with ambiguous use-associations. Record where they were so
// we can report the error if it is used.
class UseErrorDetails {
public:
  UseErrorDetails(const UseDetails &);
  UseErrorDetails &add_occurrence(const SourceName &, const Scope &);
  using listType = std::list<std::pair<SourceName, const Scope *>>;
  const listType occurrences() const { return occurrences_; };

private:
  listType occurrences_;
};

// A symbol host-associated from an enclosing scope.
class HostAssocDetails {
public:
  HostAssocDetails(const Symbol &symbol) : symbol_{symbol} {}
  const Symbol &symbol() const { return symbol_; }
  bool implicitOrSpecExprError{false};
  bool implicitOrExplicitTypeError{false};

private:
  SymbolRef symbol_;
};

// A GenericKind is one of: generic name, defined operator,
// defined assignment, intrinsic operator, or defined I/O.
struct GenericKind {
  ENUM_CLASS(OtherKind, Name, DefinedOp, Assignment, Concat)
  ENUM_CLASS(DefinedIo, // defined io
      ReadFormatted, ReadUnformatted, WriteFormatted, WriteUnformatted)
  GenericKind() : u{OtherKind::Name} {}
  template <typename T> GenericKind(const T &x) { u = x; }
  bool IsName() const { return Is(OtherKind::Name); }
  bool IsAssignment() const { return Is(OtherKind::Assignment); }
  bool IsDefinedOperator() const { return Is(OtherKind::DefinedOp); }
  bool IsIntrinsicOperator() const;
  bool IsOperator() const;
  std::string ToString() const;
  std::variant<OtherKind, common::NumericOperator, common::LogicalOperator,
      common::RelationalOperator, DefinedIo>
      u;

private:
  template <typename T> bool Has() const {
    return std::holds_alternative<T>(u);
  }
  bool Is(OtherKind) const;
};

// A generic interface or type-bound generic.
class GenericDetails {
public:
  GenericDetails() {}

  GenericKind kind() const { return kind_; }
  void set_kind(GenericKind kind) { kind_ = kind; }

  const SymbolVector &specificProcs() const { return specificProcs_; }
  const std::vector<SourceName> &bindingNames() const { return bindingNames_; }
  void AddSpecificProc(const Symbol &, SourceName bindingName);
  const SymbolVector &uses() const { return uses_; }

  // specific and derivedType indicate a specific procedure or derived type
  // with the same name as this generic. Only one of them may be set.
  Symbol *specific() { return specific_; }
  const Symbol *specific() const { return specific_; }
  void set_specific(Symbol &specific);
  Symbol *derivedType() { return derivedType_; }
  const Symbol *derivedType() const { return derivedType_; }
  void set_derivedType(Symbol &derivedType);
  void AddUse(const Symbol &);

  // Copy in specificProcs, specific, and derivedType from another generic
  void CopyFrom(const GenericDetails &);

  // Check that specific is one of the specificProcs. If not, return the
  // specific as a raw pointer.
  const Symbol *CheckSpecific() const;
  Symbol *CheckSpecific();

private:
  GenericKind kind_;
  // all of the specific procedures for this generic
  SymbolVector specificProcs_;
  std::vector<SourceName> bindingNames_;
  // Symbols used from other modules merged into this one
  SymbolVector uses_;
  // a specific procedure with the same name as this generic, if any
  Symbol *specific_{nullptr};
  // a derived type with the same name as this generic, if any
  Symbol *derivedType_{nullptr};
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const GenericDetails &);

class UnknownDetails {};

using Details = std::variant<UnknownDetails, MainProgramDetails, ModuleDetails,
    SubprogramDetails, SubprogramNameDetails, EntityDetails,
    ObjectEntityDetails, ProcEntityDetails, AssocEntityDetails,
    DerivedTypeDetails, UseDetails, UseErrorDetails, HostAssocDetails,
    GenericDetails, ProcBindingDetails, NamelistDetails, CommonBlockDetails,
    TypeParamDetails, MiscDetails>;
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Details &);
std::string DetailsToString(const Details &);

class Symbol {
public:
  ENUM_CLASS(Flag,
      Function, // symbol is a function
      Subroutine, // symbol is a subroutine
      StmtFunction, // symbol is a statement function (Function is set too)
      Implicit, // symbol is implicitly typed
      ImplicitOrError, // symbol must be implicitly typed or it's an error
      ModFile, // symbol came from .mod file
      ParentComp, // symbol is the "parent component" of an extended type
      CrayPointer, CrayPointee,
      LocalityLocal, // named in LOCAL locality-spec
      LocalityLocalInit, // named in LOCAL_INIT locality-spec
      LocalityShared, // named in SHARED locality-spec
      InDataStmt, // initialized in a DATA statement
      InNamelist, // flag is set if the symbol is in Namelist statement
      CompilerCreated,
      // OpenACC data-sharing attribute
      AccPrivate, AccFirstPrivate, AccShared,
      // OpenACC data-mapping attribute
      AccCopyIn, AccCopyOut, AccCreate, AccDelete, AccPresent,
      // OpenACC miscellaneous flags
      AccCommonBlock, AccThreadPrivate, AccReduction, AccNone, AccPreDetermined,
      // OpenMP data-sharing attribute
      OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
      // OpenMP data-mapping attribute
      OmpMapTo, OmpMapFrom, OmpMapAlloc, OmpMapRelease, OmpMapDelete,
      // OpenMP data-copying attribute
      OmpCopyIn, OmpCopyPrivate,
      // OpenMP miscellaneous flags
      OmpCommonBlock, OmpReduction, OmpAligned, OmpNontemporal, OmpAllocate,
      OmpDeclarativeAllocateDirective, OmpExecutableAllocateDirective,
      OmpDeclareSimd, OmpDeclareTarget, OmpThreadprivate, OmpDeclareReduction,
      OmpFlushed, OmpCriticalLock, OmpIfSpecified, OmpNone, OmpPreDetermined);
  using Flags = common::EnumSet<Flag, Flag_enumSize>;

  const Scope &owner() const { return *owner_; }
  const SourceName &name() const { return name_; }
  Attrs &attrs() { return attrs_; }
  const Attrs &attrs() const { return attrs_; }
  Flags &flags() { return flags_; }
  const Flags &flags() const { return flags_; }
  bool test(Flag flag) const { return flags_.test(flag); }
  void set(Flag flag, bool value = true) { flags_.set(flag, value); }
  // The Scope introduced by this symbol, if any.
  Scope *scope() { return scope_; }
  const Scope *scope() const { return scope_; }
  void set_scope(Scope *scope) { scope_ = scope; }
  std::size_t size() const { return size_; }
  void set_size(std::size_t size) { size_ = size; }
  std::size_t offset() const { return offset_; }
  void set_offset(std::size_t offset) { offset_ = offset; }
  // Give the symbol a name with a different source location but same chars.
  void ReplaceName(const SourceName &);

  // Does symbol have this type of details?
  template <typename D> bool has() const {
    return std::holds_alternative<D>(details_);
  }

  // Return a non-owning pointer to details if it is type D, else nullptr.
  template <typename D> D *detailsIf() { return std::get_if<D>(&details_); }
  template <typename D> const D *detailsIf() const {
    return std::get_if<D>(&details_);
  }

  // Return a reference to the details which must be of type D.
  template <typename D> D &get() {
    return const_cast<D &>(const_cast<const Symbol *>(this)->get<D>());
  }
  template <typename D> const D &get() const {
    const auto *p{detailsIf<D>()};
    CHECK(p);
    return *p;
  }

  Details &details() { return details_; }
  const Details &details() const { return details_; }
  // Assign the details of the symbol from one of the variants.
  // Only allowed in certain cases.
  void set_details(Details &&);

  // Can the details of this symbol be replaced with the given details?
  bool CanReplaceDetails(const Details &details) const;

  // Follow use-associations and host-associations to get the ultimate entity.
  inline Symbol &GetUltimate();
  inline const Symbol &GetUltimate() const;

  inline DeclTypeSpec *GetType();
  inline const DeclTypeSpec *GetType() const;
  void SetType(const DeclTypeSpec &);

  const std::string *GetBindName() const;
  void SetBindName(std::string &&);
  bool IsFuncResult() const;
  bool IsObjectArray() const;
  bool IsSubprogram() const;
  bool IsFromModFile() const;
  bool HasExplicitInterface() const {
    return std::visit(common::visitors{
                          [](const SubprogramDetails &) { return true; },
                          [](const SubprogramNameDetails &) { return true; },
                          [&](const ProcEntityDetails &x) {
                            return attrs_.test(Attr::INTRINSIC) ||
                                x.HasExplicitInterface();
                          },
                          [](const ProcBindingDetails &x) {
                            return x.symbol().HasExplicitInterface();
                          },
                          [](const UseDetails &x) {
                            return x.symbol().HasExplicitInterface();
                          },
                          [](const HostAssocDetails &x) {
                            return x.symbol().HasExplicitInterface();
                          },
                          [](const auto &) { return false; },
                      },
        details_);
  }

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

  int Rank() const {
    return std::visit(
        common::visitors{
            [](const SubprogramDetails &sd) {
              return sd.isFunction() ? sd.result().Rank() : 0;
            },
            [](const GenericDetails &) {
              return 0; /*TODO*/
            },
            [](const ProcBindingDetails &x) { return x.symbol().Rank(); },
            [](const UseDetails &x) { return x.symbol().Rank(); },
            [](const HostAssocDetails &x) { return x.symbol().Rank(); },
            [](const ObjectEntityDetails &oed) { return oed.shape().Rank(); },
            [](const AssocEntityDetails &aed) {
              if (const auto &expr{aed.expr()}) {
                if (auto assocRank{aed.rank()}) {
                  return *assocRank;
                } else {
                  return expr->Rank();
                }
              } else {
                return 0;
              }
            },
            [](const auto &) { return 0; },
        },
        details_);
  }

  int Corank() const {
    return std::visit(
        common::visitors{
            [](const SubprogramDetails &sd) {
              return sd.isFunction() ? sd.result().Corank() : 0;
            },
            [](const GenericDetails &) {
              return 0; /*TODO*/
            },
            [](const UseDetails &x) { return x.symbol().Corank(); },
            [](const HostAssocDetails &x) { return x.symbol().Corank(); },
            [](const ObjectEntityDetails &oed) { return oed.coshape().Rank(); },
            [](const auto &) { return 0; },
        },
        details_);
  }

  // If there is a parent component, return a pointer to its derived type spec.
  // The Scope * argument defaults to this->scope_ but should be overridden
  // for a parameterized derived type instantiation with the instance's scope.
  const DerivedTypeSpec *GetParentTypeSpec(const Scope * = nullptr) const;

  SemanticsContext &GetSemanticsContext() const;

private:
  const Scope *owner_;
  SourceName name_;
  Attrs attrs_;
  Flags flags_;
  Scope *scope_{nullptr};
  std::size_t size_{0}; // size in bytes
  std::size_t offset_{0}; // byte offset in scope or common block
  Details details_;

  Symbol() {} // only created in class Symbols
  const std::string GetDetailsName() const;
  friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Symbol &);
  friend llvm::raw_ostream &DumpForUnparse(
      llvm::raw_ostream &, const Symbol &, bool);

  // If a derived type's symbol refers to an extended derived type,
  // return the parent component's symbol.  The scope of the derived type
  // can be overridden.
  const Symbol *GetParentComponent(const Scope * = nullptr) const;

  template <std::size_t> friend class Symbols;
  template <class, std::size_t> friend struct std::array;
};

llvm::raw_ostream &operator<<(llvm::raw_ostream &, Symbol::Flag);

// Manage memory for all symbols. BLOCK_SIZE symbols at a time are allocated.
// Make() returns a reference to the next available one. They are never
// deleted.
template <std::size_t BLOCK_SIZE> class Symbols {
public:
  Symbol &Make(const Scope &owner, const SourceName &name, const Attrs &attrs,
      Details &&details) {
    Symbol &symbol = Get();
    symbol.owner_ = &owner;
    symbol.name_ = name;
    symbol.attrs_ = attrs;
    symbol.details_ = std::move(details);
    return symbol;
  }

private:
  using blockType = std::array<Symbol, BLOCK_SIZE>;
  std::list<blockType *> blocks_;
  std::size_t nextIndex_{0};
  blockType *currBlock_{nullptr};

  Symbol &Get() {
    if (nextIndex_ == 0) {
      blocks_.push_back(new blockType());
      currBlock_ = blocks_.back();
    }
    Symbol &result = (*currBlock_)[nextIndex_];
    if (++nextIndex_ >= BLOCK_SIZE) {
      nextIndex_ = 0; // allocate a new block next time
    }
    return result;
  }
};

// Define a few member functions here in the header so that they
// can be used by lib/Evaluate without inducing a dependence cycle
// between the two shared libraries.

inline bool ProcEntityDetails::HasExplicitInterface() const {
  if (auto *symbol{interface_.symbol()}) {
    return symbol->HasExplicitInterface();
  }
  return false;
}

inline Symbol &Symbol::GetUltimate() {
  return const_cast<Symbol &>(const_cast<const Symbol *>(this)->GetUltimate());
}
inline const Symbol &Symbol::GetUltimate() const {
  if (const auto *details{detailsIf<UseDetails>()}) {
    return details->symbol().GetUltimate();
  } else if (const auto *details{detailsIf<HostAssocDetails>()}) {
    return details->symbol().GetUltimate();
  } else {
    return *this;
  }
}

inline DeclTypeSpec *Symbol::GetType() {
  return const_cast<DeclTypeSpec *>(
      const_cast<const Symbol *>(this)->GetType());
}
inline const DeclTypeSpec *Symbol::GetType() const {
  return std::visit(
      common::visitors{
          [](const EntityDetails &x) { return x.type(); },
          [](const ObjectEntityDetails &x) { return x.type(); },
          [](const AssocEntityDetails &x) { return x.type(); },
          [](const SubprogramDetails &x) {
            return x.isFunction() ? x.result().GetType() : nullptr;
          },
          [](const ProcEntityDetails &x) {
            const Symbol *symbol{x.interface().symbol()};
            return symbol ? symbol->GetType() : x.interface().type();
          },
          [](const ProcBindingDetails &x) { return x.symbol().GetType(); },
          [](const TypeParamDetails &x) { return x.type(); },
          [](const UseDetails &x) { return x.symbol().GetType(); },
          [](const HostAssocDetails &x) { return x.symbol().GetType(); },
          [](const auto &) -> const DeclTypeSpec * { return nullptr; },
      },
      details_);
}

// Sets and maps keyed by Symbols

struct SymbolAddressCompare {
  bool operator()(const SymbolRef &x, const SymbolRef &y) const {
    return &*x < &*y;
  }
  bool operator()(const MutableSymbolRef &x, const MutableSymbolRef &y) const {
    return &*x < &*y;
  }
};

// Symbol comparison is usually based on the order of cooked source
// stream creation and, when both are from the same cooked source,
// their positions in that cooked source stream.
// Don't use this comparator or OrderedSymbolSet to hold
// Symbols that might be subject to ReplaceName().
struct SymbolSourcePositionCompare {
  // These functions are implemented in Evaluate/tools.cpp to
  // satisfy complicated shared library interdependency.
  bool operator()(const SymbolRef &, const SymbolRef &) const;
  bool operator()(const MutableSymbolRef &, const MutableSymbolRef &) const;
};

struct SymbolOffsetCompare {
  bool operator()(const SymbolRef &, const SymbolRef &) const;
  bool operator()(const MutableSymbolRef &, const MutableSymbolRef &) const;
};

using UnorderedSymbolSet = std::set<SymbolRef, SymbolAddressCompare>;
using SourceOrderedSymbolSet = std::set<SymbolRef, SymbolSourcePositionCompare>;

template <typename A>
SourceOrderedSymbolSet OrderBySourcePosition(const A &container) {
  SourceOrderedSymbolSet result;
  for (SymbolRef x : container) {
    result.emplace(x);
  }
  return result;
}

} // namespace Fortran::semantics

// Define required  info so that SymbolRef can be used inside llvm::DenseMap.
namespace llvm {
template <> struct DenseMapInfo<Fortran::semantics::SymbolRef> {
  static inline Fortran::semantics::SymbolRef getEmptyKey() {
    auto ptr = DenseMapInfo<const Fortran::semantics::Symbol *>::getEmptyKey();
    return *reinterpret_cast<Fortran::semantics::SymbolRef *>(&ptr);
  }

  static inline Fortran::semantics::SymbolRef getTombstoneKey() {
    auto ptr =
        DenseMapInfo<const Fortran::semantics::Symbol *>::getTombstoneKey();
    return *reinterpret_cast<Fortran::semantics::SymbolRef *>(&ptr);
  }

  static unsigned getHashValue(const Fortran::semantics::SymbolRef &sym) {
    return DenseMapInfo<const Fortran::semantics::Symbol *>::getHashValue(
        &sym.get());
  }

  static bool isEqual(const Fortran::semantics::SymbolRef &LHS,
      const Fortran::semantics::SymbolRef &RHS) {
    return LHS == RHS;
  }
};
} // namespace llvm
#endif // FORTRAN_SEMANTICS_SYMBOL_H_
