102class ExpressionAnalyzer {
 
  104  using MaybeExpr = std::optional<Expr<SomeType>>;
 
  108      : context_{sc}, foldingContext_{fc} {}
 
  109  ExpressionAnalyzer(
const ExpressionAnalyzer &) = 
default;
 
  112  bool inWhereBody()
 const { 
return inWhereBody_; }
 
  113  void set_inWhereBody(
bool yes = 
true) { inWhereBody_ = yes; }
 
  114  bool inDataStmtObject()
 const { 
return inDataStmtObject_; }
 
  115  void set_inDataStmtObject(
bool yes = 
true) { inDataStmtObject_ = yes; }
 
  117  FoldingContext &GetFoldingContext()
 const { 
return foldingContext_; }
 
  120    return foldingContext_.messages();
 
  124    return GetContextualMessages().Say(std::forward<A>(args)...);
 
  126  template <
typename FeatureOrUsageWarning, 
typename... A>
 
  129    return context_.Warn(warning, at, std::forward<A>(args)...);
 
  131  template <
typename FeatureOrUsageWarning, 
typename... A>
 
  134        warning, GetContextualMessages().at(), std::forward<A>(args)...);
 
  137  template <
typename T, 
typename... A>
 
  139    return Say(parser::FindSourceLocation(parsed), std::forward<A>(args)...);
 
  142  int GetDefaultKind(common::TypeCategory);
 
  143  DynamicType GetDefaultKindOfType(common::TypeCategory);
 
  146  bool CheckIntrinsicKind(TypeCategory, std::int64_t kind);
 
  147  bool CheckIntrinsicSize(TypeCategory, std::int64_t size);
 
  158    return common::ScopedSet(useSavedTypedExprs_, 
false);
 
  162      const std::optional<parser::KindSelector> &);
 
  173    return Analyze(x.value());
 
  175  template <
typename A> MaybeExpr Analyze(
const std::optional<A> &x) {
 
  185    auto result{Analyze(x.thing)};
 
  187      if (
int rank{result->Rank()}; rank != 0) {
 
  188        SayAt(x, 
"Must be a scalar value, but is a rank-%d array"_err_en_US,
 
  198        GetFoldingContext().messages().SetLocation(FindSourceLocation(x))};
 
  199    auto result{Analyze(x.thing)};
 
  201      *result = Fold(std::move(*result));
 
  202      if (!IsConstantExpr(*result)) { 
 
  203        SayAt(x, 
"Must be a constant value"_err_en_US);
 
  208        SetExpr(x, common::Clone(*result));
 
  214    auto result{Analyze(x.thing)};
 
  215    if (!EnforceTypeConstraint(
 
  216            parser::FindSourceLocation(x), result, TypeCategory::Integer)) {
 
  223    auto result{Analyze(x.thing)};
 
  224    if (!EnforceTypeConstraint(
 
  225            parser::FindSourceLocation(x), result, TypeCategory::Logical)) {
 
  232    auto result{Analyze(x.thing)};
 
  233    if (!EnforceTypeConstraint(parser::FindSourceLocation(x), result,
 
  234            TypeCategory::Character, 
true )) {
 
  243    return Analyze<parser::DataRef>(dr);
 
  250  MaybeExpr Analyze(
const parser::InitialDataTarget &);
 
  251  MaybeExpr Analyze(
const parser::NullInit &);
 
  259  MaybeExpr Designate(
DataRef &&);
 
  265    return common::ScopedSet(isWholeAssumedSizeArrayOk_, yes);
 
  269  int IntegerTypeSpecKind(
const parser::IntegerTypeSpec &);
 
  274    return common::ScopedSet(isNullPointerOk_, 
true);
 
  285  MaybeExpr Analyze(
const parser::BOZLiteralConstant &);
 
  286  MaybeExpr Analyze(
const parser::NamedConstant &);
 
  293  MaybeExpr Analyze(
const parser::ArrayConstructor &);
 
  295      std::optional<parser::StructureConstructor> * = 
nullptr);
 
  300  MaybeExpr Analyze(
const parser::Expr::PercentLoc &);
 
  320  template <
typename A> MaybeExpr Analyze(
const A &x) {
 
  323  template <
typename... As> MaybeExpr Analyze(
const std::variant<As...> &u) {
 
  324    return common::visit([&](
const auto &x) { 
return Analyze(x); }, u);
 
  328  int AnalyzeKindParam(
 
  329      const std::optional<parser::KindParam> &, 
int defaultKind);
 
  330  template <
typename PARSED>
 
  332  template <
typename TYPES, TypeCategory CAT, 
typename PARSED>
 
  333  MaybeExpr IntLiteralConstant(
const PARSED &, 
bool isNegated = 
false);
 
  334  MaybeExpr AnalyzeString(std::string &&, 
int kind);
 
  335  std::optional<Expr<SubscriptInteger>> AsSubscript(MaybeExpr &&);
 
  336  std::optional<Expr<SubscriptInteger>> TripletPart(
 
  337      const std::optional<parser::Subscript> &);
 
  338  std::optional<Subscript> AnalyzeSectionSubscript(
 
  340  std::vector<Subscript> AnalyzeSectionSubscripts(
 
  341      const std::list<parser::SectionSubscript> &);
 
  342  std::optional<Component> CreateComponent(
DataRef &&, 
const Symbol &,
 
  344  MaybeExpr CompleteSubscripts(
ArrayRef &&);
 
  345  MaybeExpr ApplySubscripts(
DataRef &&, std::vector<Subscript> &&);
 
  346  bool CheckRanks(
const DataRef &); 
 
  347  bool CheckPolymorphic(
const DataRef &); 
 
  348  bool CheckDataRef(
const DataRef &); 
 
  349  std::optional<Expr<SubscriptInteger>> GetSubstringBound(
 
  350      const std::optional<parser::ScalarIntExpr> &);
 
  351  MaybeExpr AnalyzeDefinedOp(
 
  355  struct CalleeAndArguments {
 
  359    std::variant<ProcedureDesignator, SymbolRef> u;
 
  360    ActualArguments arguments;
 
  363  std::optional<CalleeAndArguments> AnalyzeProcedureComponentRef(
 
  365  std::optional<characteristics::Procedure> CheckCall(
 
  367  using AdjustActuals =
 
  368      std::optional<std::function<bool(
const Symbol &, ActualArguments &)>>;
 
  370  struct GenericResolution {
 
  371    const Symbol *specific{
nullptr};
 
  372    bool failedDueToAmbiguity{
false};
 
  373    SymbolVector tried{};
 
  375  GenericResolution ResolveGeneric(
const Symbol &, 
const ActualArguments &,
 
  376      const AdjustActuals &, 
bool isSubroutine, SymbolVector &&tried,
 
  377      bool mightBeStructureConstructor = 
false);
 
  378  void EmitGenericResolutionError(
const Symbol &, 
bool dueToNullActuals,
 
  379      bool isSubroutine, ActualArguments &, 
const SymbolVector &);
 
  380  const Symbol &AccessSpecific(
 
  382  std::optional<CalleeAndArguments> GetCalleeAndArguments(
const parser::Name &,
 
  383      ActualArguments &&, 
bool isSubroutine = 
false,
 
  384      bool mightBeStructureConstructor = 
false);
 
  385  std::optional<CalleeAndArguments> GetCalleeAndArguments(
 
  387      bool isSubroutine, 
bool mightBeStructureConstructor = 
false);
 
  391      bool defaultKind = 
false);
 
  392  MaybeExpr MakeFunctionRef(
 
  395  template <
typename T> T Fold(T &&expr) {
 
  396    return evaluate::Fold(foldingContext_, std::move(expr));
 
  399  MaybeExpr AnalyzeComplex(MaybeExpr &&re, MaybeExpr &&im, 
const char *what);
 
  404  struct ComponentSpec {
 
  405    ComponentSpec() = 
default;
 
  406    ComponentSpec(ComponentSpec &&) = 
default;
 
  408    bool hasKeyword{
false};
 
  409    const Symbol *keywordSymbol{
nullptr};
 
  415  MaybeExpr IterativelyAnalyzeSubexpressions(
const parser::Expr &);
 
  419  std::map<parser::CharBlock, int> impliedDos_; 
 
  421      std::pair<parser::CharBlock, evaluate::characteristics::Procedure>>
 
  423  bool isWholeAssumedSizeArrayOk_{
false};
 
  424  bool isNullPointerOk_{
false};
 
  425  bool useSavedTypedExprs_{
true};
 
  426  bool inWhereBody_{
false};
 
  427  bool inDataStmtObject_{
false};
 
  428  bool inDataStmtConstant_{
false};
 
  429  bool inStmtFunctionDefinition_{
false};
 
  430  bool iterativelyAnalyzingSubexpressions_{
false};
 
  431  friend class ArgumentAnalyzer;