1 //===-- lib/Semantics/resolve-names.cpp -----------------------------------===//
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7 
8 #include "resolve-names.h"
9 #include "assignment.h"
10 #include "mod-file.h"
11 #include "pointer-assignment.h"
12 #include "program-tree.h"
13 #include "resolve-directives.h"
14 #include "resolve-names-utils.h"
15 #include "rewrite-parse-tree.h"
16 #include "flang/Common/Fortran.h"
17 #include "flang/Common/default-kinds.h"
18 #include "flang/Common/indirection.h"
19 #include "flang/Common/restorer.h"
20 #include "flang/Evaluate/characteristics.h"
21 #include "flang/Evaluate/check-expression.h"
22 #include "flang/Evaluate/common.h"
23 #include "flang/Evaluate/fold-designator.h"
24 #include "flang/Evaluate/fold.h"
25 #include "flang/Evaluate/intrinsics.h"
26 #include "flang/Evaluate/tools.h"
27 #include "flang/Evaluate/type.h"
28 #include "flang/Parser/parse-tree-visitor.h"
29 #include "flang/Parser/parse-tree.h"
30 #include "flang/Parser/tools.h"
31 #include "flang/Semantics/attr.h"
32 #include "flang/Semantics/expression.h"
33 #include "flang/Semantics/scope.h"
34 #include "flang/Semantics/semantics.h"
35 #include "flang/Semantics/symbol.h"
36 #include "flang/Semantics/tools.h"
37 #include "flang/Semantics/type.h"
38 #include "llvm/Support/raw_ostream.h"
39 #include <list>
40 #include <map>
41 #include <set>
42 #include <stack>
43 
44 namespace Fortran::semantics {
45 
46 using namespace parser::literals;
47 
48 template <typename T> using Indirection = common::Indirection<T>;
49 using Message = parser::Message;
50 using Messages = parser::Messages;
51 using MessageFixedText = parser::MessageFixedText;
52 using MessageFormattedText = parser::MessageFormattedText;
53 
54 class ResolveNamesVisitor;
55 
56 // ImplicitRules maps initial character of identifier to the DeclTypeSpec
57 // representing the implicit type; std::nullopt if none.
58 // It also records the presence of IMPLICIT NONE statements.
59 // When inheritFromParent is set, defaults come from the parent rules.
60 class ImplicitRules {
61 public:
62   ImplicitRules(SemanticsContext &context, ImplicitRules *parent)
63       : parent_{parent}, context_{context} {
64     inheritFromParent_ = parent != nullptr;
65   }
66   bool isImplicitNoneType() const;
67   bool isImplicitNoneExternal() const;
68   void set_isImplicitNoneType(bool x) { isImplicitNoneType_ = x; }
69   void set_isImplicitNoneExternal(bool x) { isImplicitNoneExternal_ = x; }
70   void set_inheritFromParent(bool x) { inheritFromParent_ = x; }
71   // Get the implicit type for this name. May be null.
72   const DeclTypeSpec *GetType(
73       SourceName, bool respectImplicitNone = true) const;
74   // Record the implicit type for the range of characters [fromLetter,
75   // toLetter].
76   void SetTypeMapping(const DeclTypeSpec &type, parser::Location fromLetter,
77       parser::Location toLetter);
78 
79 private:
80   static char Incr(char ch);
81 
82   ImplicitRules *parent_;
83   SemanticsContext &context_;
84   bool inheritFromParent_{false}; // look in parent if not specified here
85   bool isImplicitNoneType_{
86       context_.IsEnabled(common::LanguageFeature::ImplicitNoneTypeAlways)};
87   bool isImplicitNoneExternal_{false};
88   // map_ contains the mapping between letters and types that were defined
89   // by the IMPLICIT statements of the related scope. It does not contain
90   // the default Fortran mappings nor the mapping defined in parents.
91   std::map<char, common::Reference<const DeclTypeSpec>> map_;
92 
93   friend llvm::raw_ostream &operator<<(
94       llvm::raw_ostream &, const ImplicitRules &);
95   friend void ShowImplicitRule(
96       llvm::raw_ostream &, const ImplicitRules &, char);
97 };
98 
99 // scope -> implicit rules for that scope
100 using ImplicitRulesMap = std::map<const Scope *, ImplicitRules>;
101 
102 // Track statement source locations and save messages.
103 class MessageHandler {
104 public:
105   MessageHandler() { DIE("MessageHandler: default-constructed"); }
106   explicit MessageHandler(SemanticsContext &c) : context_{&c} {}
107   Messages &messages() { return context_->messages(); };
108   const std::optional<SourceName> &currStmtSource() {
109     return context_->location();
110   }
111   void set_currStmtSource(const std::optional<SourceName> &source) {
112     context_->set_location(source);
113   }
114 
115   // Emit a message associated with the current statement source.
116   Message &Say(MessageFixedText &&);
117   Message &Say(MessageFormattedText &&);
118   // Emit a message about a SourceName
119   Message &Say(const SourceName &, MessageFixedText &&);
120   // Emit a formatted message associated with a source location.
121   template <typename... A>
122   Message &Say(const SourceName &source, MessageFixedText &&msg, A &&...args) {
123     return context_->Say(source, std::move(msg), std::forward<A>(args)...);
124   }
125 
126 private:
127   SemanticsContext *context_;
128 };
129 
130 // Inheritance graph for the parse tree visitation classes that follow:
131 //   BaseVisitor
132 //   + AttrsVisitor
133 //   | + DeclTypeSpecVisitor
134 //   |   + ImplicitRulesVisitor
135 //   |     + ScopeHandler -----------+--+
136 //   |       + ModuleVisitor ========|==+
137 //   |       + InterfaceVisitor      |  |
138 //   |       +-+ SubprogramVisitor ==|==+
139 //   + ArraySpecVisitor              |  |
140 //     + DeclarationVisitor <--------+  |
141 //       + ConstructVisitor             |
142 //         + ResolveNamesVisitor <------+
143 
144 class BaseVisitor {
145 public:
146   BaseVisitor() { DIE("BaseVisitor: default-constructed"); }
147   BaseVisitor(
148       SemanticsContext &c, ResolveNamesVisitor &v, ImplicitRulesMap &rules)
149       : implicitRulesMap_{&rules}, this_{&v}, context_{&c}, messageHandler_{c} {
150   }
151   template <typename T> void Walk(const T &);
152 
153   MessageHandler &messageHandler() { return messageHandler_; }
154   const std::optional<SourceName> &currStmtSource() {
155     return context_->location();
156   }
157   SemanticsContext &context() const { return *context_; }
158   evaluate::FoldingContext &GetFoldingContext() const {
159     return context_->foldingContext();
160   }
161   bool IsIntrinsic(
162       const SourceName &name, std::optional<Symbol::Flag> flag) const {
163     if (!flag) {
164       return context_->intrinsics().IsIntrinsic(name.ToString());
165     } else if (flag == Symbol::Flag::Function) {
166       return context_->intrinsics().IsIntrinsicFunction(name.ToString());
167     } else if (flag == Symbol::Flag::Subroutine) {
168       return context_->intrinsics().IsIntrinsicSubroutine(name.ToString());
169     } else {
170       DIE("expected Subroutine or Function flag");
171     }
172   }
173 
174   // Make a placeholder symbol for a Name that otherwise wouldn't have one.
175   // It is not in any scope and always has MiscDetails.
176   void MakePlaceholder(const parser::Name &, MiscDetails::Kind);
177 
178   template <typename T> common::IfNoLvalue<T, T> FoldExpr(T &&expr) {
179     return evaluate::Fold(GetFoldingContext(), std::move(expr));
180   }
181 
182   template <typename T> MaybeExpr EvaluateExpr(const T &expr) {
183     return FoldExpr(AnalyzeExpr(*context_, expr));
184   }
185 
186   template <typename T>
187   MaybeExpr EvaluateNonPointerInitializer(
188       const Symbol &symbol, const T &expr, parser::CharBlock source) {
189     if (!context().HasError(symbol)) {
190       if (auto maybeExpr{AnalyzeExpr(*context_, expr)}) {
191         auto restorer{GetFoldingContext().messages().SetLocation(source)};
192         return evaluate::NonPointerInitializationExpr(
193             symbol, std::move(*maybeExpr), GetFoldingContext());
194       }
195     }
196     return std::nullopt;
197   }
198 
199   template <typename T> MaybeIntExpr EvaluateIntExpr(const T &expr) {
200     return semantics::EvaluateIntExpr(*context_, expr);
201   }
202 
203   template <typename T>
204   MaybeSubscriptIntExpr EvaluateSubscriptIntExpr(const T &expr) {
205     if (MaybeIntExpr maybeIntExpr{EvaluateIntExpr(expr)}) {
206       return FoldExpr(evaluate::ConvertToType<evaluate::SubscriptInteger>(
207           std::move(*maybeIntExpr)));
208     } else {
209       return std::nullopt;
210     }
211   }
212 
213   template <typename... A> Message &Say(A &&...args) {
214     return messageHandler_.Say(std::forward<A>(args)...);
215   }
216   template <typename... A>
217   Message &Say(
218       const parser::Name &name, MessageFixedText &&text, const A &...args) {
219     return messageHandler_.Say(name.source, std::move(text), args...);
220   }
221 
222 protected:
223   ImplicitRulesMap *implicitRulesMap_{nullptr};
224 
225 private:
226   ResolveNamesVisitor *this_;
227   SemanticsContext *context_;
228   MessageHandler messageHandler_;
229 };
230 
231 // Provide Post methods to collect attributes into a member variable.
232 class AttrsVisitor : public virtual BaseVisitor {
233 public:
234   bool BeginAttrs(); // always returns true
235   Attrs GetAttrs();
236   Attrs EndAttrs();
237   bool SetPassNameOn(Symbol &);
238   void SetBindNameOn(Symbol &);
239   void Post(const parser::LanguageBindingSpec &);
240   bool Pre(const parser::IntentSpec &);
241   bool Pre(const parser::Pass &);
242 
243   bool CheckAndSet(Attr);
244 
245 // Simple case: encountering CLASSNAME causes ATTRNAME to be set.
246 #define HANDLE_ATTR_CLASS(CLASSNAME, ATTRNAME) \
247   bool Pre(const parser::CLASSNAME &) { \
248     CheckAndSet(Attr::ATTRNAME); \
249     return false; \
250   }
251   HANDLE_ATTR_CLASS(PrefixSpec::Elemental, ELEMENTAL)
252   HANDLE_ATTR_CLASS(PrefixSpec::Impure, IMPURE)
253   HANDLE_ATTR_CLASS(PrefixSpec::Module, MODULE)
254   HANDLE_ATTR_CLASS(PrefixSpec::Non_Recursive, NON_RECURSIVE)
255   HANDLE_ATTR_CLASS(PrefixSpec::Pure, PURE)
256   HANDLE_ATTR_CLASS(PrefixSpec::Recursive, RECURSIVE)
257   HANDLE_ATTR_CLASS(TypeAttrSpec::BindC, BIND_C)
258   HANDLE_ATTR_CLASS(BindAttr::Deferred, DEFERRED)
259   HANDLE_ATTR_CLASS(BindAttr::Non_Overridable, NON_OVERRIDABLE)
260   HANDLE_ATTR_CLASS(Abstract, ABSTRACT)
261   HANDLE_ATTR_CLASS(Allocatable, ALLOCATABLE)
262   HANDLE_ATTR_CLASS(Asynchronous, ASYNCHRONOUS)
263   HANDLE_ATTR_CLASS(Contiguous, CONTIGUOUS)
264   HANDLE_ATTR_CLASS(External, EXTERNAL)
265   HANDLE_ATTR_CLASS(Intrinsic, INTRINSIC)
266   HANDLE_ATTR_CLASS(NoPass, NOPASS)
267   HANDLE_ATTR_CLASS(Optional, OPTIONAL)
268   HANDLE_ATTR_CLASS(Parameter, PARAMETER)
269   HANDLE_ATTR_CLASS(Pointer, POINTER)
270   HANDLE_ATTR_CLASS(Protected, PROTECTED)
271   HANDLE_ATTR_CLASS(Save, SAVE)
272   HANDLE_ATTR_CLASS(Target, TARGET)
273   HANDLE_ATTR_CLASS(Value, VALUE)
274   HANDLE_ATTR_CLASS(Volatile, VOLATILE)
275 #undef HANDLE_ATTR_CLASS
276 
277 protected:
278   std::optional<Attrs> attrs_;
279 
280   Attr AccessSpecToAttr(const parser::AccessSpec &x) {
281     switch (x.v) {
282     case parser::AccessSpec::Kind::Public:
283       return Attr::PUBLIC;
284     case parser::AccessSpec::Kind::Private:
285       return Attr::PRIVATE;
286     }
287     llvm_unreachable("Switch covers all cases"); // suppress g++ warning
288   }
289   Attr IntentSpecToAttr(const parser::IntentSpec &x) {
290     switch (x.v) {
291     case parser::IntentSpec::Intent::In:
292       return Attr::INTENT_IN;
293     case parser::IntentSpec::Intent::Out:
294       return Attr::INTENT_OUT;
295     case parser::IntentSpec::Intent::InOut:
296       return Attr::INTENT_INOUT;
297     }
298     llvm_unreachable("Switch covers all cases"); // suppress g++ warning
299   }
300 
301 private:
302   bool IsDuplicateAttr(Attr);
303   bool HaveAttrConflict(Attr, Attr, Attr);
304   bool IsConflictingAttr(Attr);
305 
306   MaybeExpr bindName_; // from BIND(C, NAME="...")
307   std::optional<SourceName> passName_; // from PASS(...)
308 };
309 
310 // Find and create types from declaration-type-spec nodes.
311 class DeclTypeSpecVisitor : public AttrsVisitor {
312 public:
313   using AttrsVisitor::Post;
314   using AttrsVisitor::Pre;
315   void Post(const parser::IntrinsicTypeSpec::DoublePrecision &);
316   void Post(const parser::IntrinsicTypeSpec::DoubleComplex &);
317   void Post(const parser::DeclarationTypeSpec::ClassStar &);
318   void Post(const parser::DeclarationTypeSpec::TypeStar &);
319   bool Pre(const parser::TypeGuardStmt &);
320   void Post(const parser::TypeGuardStmt &);
321   void Post(const parser::TypeSpec &);
322 
323 protected:
324   struct State {
325     bool expectDeclTypeSpec{false}; // should see decl-type-spec only when true
326     const DeclTypeSpec *declTypeSpec{nullptr};
327     struct {
328       DerivedTypeSpec *type{nullptr};
329       DeclTypeSpec::Category category{DeclTypeSpec::TypeDerived};
330     } derived;
331     bool allowForwardReferenceToDerivedType{false};
332   };
333 
334   bool allowForwardReferenceToDerivedType() const {
335     return state_.allowForwardReferenceToDerivedType;
336   }
337   void set_allowForwardReferenceToDerivedType(bool yes) {
338     state_.allowForwardReferenceToDerivedType = yes;
339   }
340 
341   // Walk the parse tree of a type spec and return the DeclTypeSpec for it.
342   template <typename T>
343   const DeclTypeSpec *ProcessTypeSpec(const T &x, bool allowForward = false) {
344     auto restorer{common::ScopedSet(state_, State{})};
345     set_allowForwardReferenceToDerivedType(allowForward);
346     BeginDeclTypeSpec();
347     Walk(x);
348     const auto *type{GetDeclTypeSpec()};
349     EndDeclTypeSpec();
350     return type;
351   }
352 
353   const DeclTypeSpec *GetDeclTypeSpec();
354   void BeginDeclTypeSpec();
355   void EndDeclTypeSpec();
356   void SetDeclTypeSpec(const DeclTypeSpec &);
357   void SetDeclTypeSpecCategory(DeclTypeSpec::Category);
358   DeclTypeSpec::Category GetDeclTypeSpecCategory() const {
359     return state_.derived.category;
360   }
361   KindExpr GetKindParamExpr(
362       TypeCategory, const std::optional<parser::KindSelector> &);
363   void CheckForAbstractType(const Symbol &typeSymbol);
364 
365 private:
366   State state_;
367 
368   void MakeNumericType(TypeCategory, int kind);
369 };
370 
371 // Visit ImplicitStmt and related parse tree nodes and updates implicit rules.
372 class ImplicitRulesVisitor : public DeclTypeSpecVisitor {
373 public:
374   using DeclTypeSpecVisitor::Post;
375   using DeclTypeSpecVisitor::Pre;
376   using ImplicitNoneNameSpec = parser::ImplicitStmt::ImplicitNoneNameSpec;
377 
378   void Post(const parser::ParameterStmt &);
379   bool Pre(const parser::ImplicitStmt &);
380   bool Pre(const parser::LetterSpec &);
381   bool Pre(const parser::ImplicitSpec &);
382   void Post(const parser::ImplicitSpec &);
383 
384   const DeclTypeSpec *GetType(
385       SourceName name, bool respectImplicitNoneType = true) {
386     return implicitRules_->GetType(name, respectImplicitNoneType);
387   }
388   bool isImplicitNoneType() const {
389     return implicitRules_->isImplicitNoneType();
390   }
391   bool isImplicitNoneType(const Scope &scope) const {
392     return implicitRulesMap_->at(&scope).isImplicitNoneType();
393   }
394   bool isImplicitNoneExternal() const {
395     return implicitRules_->isImplicitNoneExternal();
396   }
397   void set_inheritFromParent(bool x) {
398     implicitRules_->set_inheritFromParent(x);
399   }
400 
401 protected:
402   void BeginScope(const Scope &);
403   void SetScope(const Scope &);
404 
405 private:
406   // implicit rules in effect for current scope
407   ImplicitRules *implicitRules_{nullptr};
408   std::optional<SourceName> prevImplicit_;
409   std::optional<SourceName> prevImplicitNone_;
410   std::optional<SourceName> prevImplicitNoneType_;
411   std::optional<SourceName> prevParameterStmt_;
412 
413   bool HandleImplicitNone(const std::list<ImplicitNoneNameSpec> &nameSpecs);
414 };
415 
416 // Track array specifications. They can occur in AttrSpec, EntityDecl,
417 // ObjectDecl, DimensionStmt, CommonBlockObject, or BasedPointerStmt.
418 // 1. INTEGER, DIMENSION(10) :: x
419 // 2. INTEGER :: x(10)
420 // 3. ALLOCATABLE :: x(:)
421 // 4. DIMENSION :: x(10)
422 // 5. COMMON x(10)
423 // 6. BasedPointerStmt
424 class ArraySpecVisitor : public virtual BaseVisitor {
425 public:
426   void Post(const parser::ArraySpec &);
427   void Post(const parser::ComponentArraySpec &);
428   void Post(const parser::CoarraySpec &);
429   void Post(const parser::AttrSpec &) { PostAttrSpec(); }
430   void Post(const parser::ComponentAttrSpec &) { PostAttrSpec(); }
431 
432 protected:
433   const ArraySpec &arraySpec();
434   void set_arraySpec(const ArraySpec arraySpec) { arraySpec_ = arraySpec; }
435   const ArraySpec &coarraySpec();
436   void BeginArraySpec();
437   void EndArraySpec();
438   void ClearArraySpec() { arraySpec_.clear(); }
439   void ClearCoarraySpec() { coarraySpec_.clear(); }
440 
441 private:
442   // arraySpec_/coarraySpec_ are populated from any ArraySpec/CoarraySpec
443   ArraySpec arraySpec_;
444   ArraySpec coarraySpec_;
445   // When an ArraySpec is under an AttrSpec or ComponentAttrSpec, it is moved
446   // into attrArraySpec_
447   ArraySpec attrArraySpec_;
448   ArraySpec attrCoarraySpec_;
449 
450   void PostAttrSpec();
451 };
452 
453 // Manage a stack of Scopes
454 class ScopeHandler : public ImplicitRulesVisitor {
455 public:
456   using ImplicitRulesVisitor::Post;
457   using ImplicitRulesVisitor::Pre;
458 
459   Scope &currScope() { return DEREF(currScope_); }
460   // The enclosing host procedure if current scope is in an internal procedure
461   Scope *GetHostProcedure();
462   // The innermost enclosing program unit scope, ignoring BLOCK and other
463   // construct scopes.
464   Scope &InclusiveScope();
465   // The enclosing scope, skipping derived types.
466   Scope &NonDerivedTypeScope();
467 
468   // Create a new scope and push it on the scope stack.
469   void PushScope(Scope::Kind kind, Symbol *symbol);
470   void PushScope(Scope &scope);
471   void PopScope();
472   void SetScope(Scope &);
473 
474   template <typename T> bool Pre(const parser::Statement<T> &x) {
475     messageHandler().set_currStmtSource(x.source);
476     currScope_->AddSourceRange(x.source);
477     return true;
478   }
479   template <typename T> void Post(const parser::Statement<T> &) {
480     messageHandler().set_currStmtSource(std::nullopt);
481   }
482 
483   // Special messages: already declared; referencing symbol's declaration;
484   // about a type; two names & locations
485   void SayAlreadyDeclared(const parser::Name &, Symbol &);
486   void SayAlreadyDeclared(const SourceName &, Symbol &);
487   void SayAlreadyDeclared(const SourceName &, const SourceName &);
488   void SayWithReason(
489       const parser::Name &, Symbol &, MessageFixedText &&, MessageFixedText &&);
490   void SayWithDecl(const parser::Name &, Symbol &, MessageFixedText &&);
491   void SayLocalMustBeVariable(const parser::Name &, Symbol &);
492   void SayDerivedType(const SourceName &, MessageFixedText &&, const Scope &);
493   void Say2(const SourceName &, MessageFixedText &&, const SourceName &,
494       MessageFixedText &&);
495   void Say2(
496       const SourceName &, MessageFixedText &&, Symbol &, MessageFixedText &&);
497   void Say2(
498       const parser::Name &, MessageFixedText &&, Symbol &, MessageFixedText &&);
499 
500   // Search for symbol by name in current, parent derived type, and
501   // containing scopes
502   Symbol *FindSymbol(const parser::Name &);
503   Symbol *FindSymbol(const Scope &, const parser::Name &);
504   // Search for name only in scope, not in enclosing scopes.
505   Symbol *FindInScope(const Scope &, const parser::Name &);
506   Symbol *FindInScope(const Scope &, const SourceName &);
507   template <typename T> Symbol *FindInScope(const T &name) {
508     return FindInScope(currScope(), name);
509   }
510   // Search for name in a derived type scope and its parents.
511   Symbol *FindInTypeOrParents(const Scope &, const parser::Name &);
512   Symbol *FindInTypeOrParents(const parser::Name &);
513   void EraseSymbol(const parser::Name &);
514   void EraseSymbol(const Symbol &symbol) { currScope().erase(symbol.name()); }
515   // Make a new symbol with the name and attrs of an existing one
516   Symbol &CopySymbol(const SourceName &, const Symbol &);
517 
518   // Make symbols in the current or named scope
519   Symbol &MakeSymbol(Scope &, const SourceName &, Attrs);
520   Symbol &MakeSymbol(const SourceName &, Attrs = Attrs{});
521   Symbol &MakeSymbol(const parser::Name &, Attrs = Attrs{});
522   Symbol &MakeHostAssocSymbol(const parser::Name &, const Symbol &);
523 
524   template <typename D>
525   common::IfNoLvalue<Symbol &, D> MakeSymbol(
526       const parser::Name &name, D &&details) {
527     return MakeSymbol(name, Attrs{}, std::move(details));
528   }
529 
530   template <typename D>
531   common::IfNoLvalue<Symbol &, D> MakeSymbol(
532       const parser::Name &name, const Attrs &attrs, D &&details) {
533     return Resolve(name, MakeSymbol(name.source, attrs, std::move(details)));
534   }
535 
536   template <typename D>
537   common::IfNoLvalue<Symbol &, D> MakeSymbol(
538       const SourceName &name, const Attrs &attrs, D &&details) {
539     // Note: don't use FindSymbol here. If this is a derived type scope,
540     // we want to detect whether the name is already declared as a component.
541     auto *symbol{FindInScope(name)};
542     if (!symbol) {
543       symbol = &MakeSymbol(name, attrs);
544       symbol->set_details(std::move(details));
545       return *symbol;
546     }
547     if constexpr (std::is_same_v<DerivedTypeDetails, D>) {
548       if (auto *d{symbol->detailsIf<GenericDetails>()}) {
549         if (!d->specific()) {
550           // derived type with same name as a generic
551           auto *derivedType{d->derivedType()};
552           if (!derivedType) {
553             derivedType =
554                 &currScope().MakeSymbol(name, attrs, std::move(details));
555             d->set_derivedType(*derivedType);
556           } else {
557             SayAlreadyDeclared(name, *derivedType);
558           }
559           return *derivedType;
560         }
561       }
562     }
563     if (symbol->CanReplaceDetails(details)) {
564       // update the existing symbol
565       symbol->attrs() |= attrs;
566       if constexpr (std::is_same_v<SubprogramDetails, D>) {
567         // Dummy argument defined by explicit interface
568         details.set_isDummy(IsDummy(*symbol));
569       }
570       symbol->set_details(std::move(details));
571       return *symbol;
572     } else if constexpr (std::is_same_v<UnknownDetails, D>) {
573       symbol->attrs() |= attrs;
574       return *symbol;
575     } else {
576       if (!CheckPossibleBadForwardRef(*symbol)) {
577         SayAlreadyDeclared(name, *symbol);
578       }
579       // replace the old symbol with a new one with correct details
580       EraseSymbol(*symbol);
581       auto &result{MakeSymbol(name, attrs, std::move(details))};
582       context().SetError(result);
583       return result;
584     }
585   }
586 
587   void MakeExternal(Symbol &);
588 
589 protected:
590   // Apply the implicit type rules to this symbol.
591   void ApplyImplicitRules(Symbol &, bool allowForwardReference = false);
592   bool ImplicitlyTypeForwardRef(Symbol &);
593   void AcquireIntrinsicProcedureFlags(Symbol &);
594   const DeclTypeSpec *GetImplicitType(
595       Symbol &, bool respectImplicitNoneType = true);
596   bool ConvertToObjectEntity(Symbol &);
597   bool ConvertToProcEntity(Symbol &);
598 
599   const DeclTypeSpec &MakeNumericType(
600       TypeCategory, const std::optional<parser::KindSelector> &);
601   const DeclTypeSpec &MakeLogicalType(
602       const std::optional<parser::KindSelector> &);
603   void NotePossibleBadForwardRef(const parser::Name &);
604   std::optional<SourceName> HadForwardRef(const Symbol &) const;
605   bool CheckPossibleBadForwardRef(const Symbol &);
606 
607   bool inExecutionPart_{false};
608   bool inSpecificationPart_{false};
609   bool inEquivalenceStmt_{false};
610 
611   // Some information is collected from a specification part for deferred
612   // processing in DeclarationPartVisitor functions (e.g., CheckSaveStmts())
613   // that are called by ResolveNamesVisitor::FinishSpecificationPart().  Since
614   // specification parts can nest (e.g., INTERFACE bodies), the collected
615   // information that is not contained in the scope needs to be packaged
616   // and restorable.
617   struct SpecificationPartState {
618     std::set<SourceName> forwardRefs;
619     // Collect equivalence sets and process at end of specification part
620     std::vector<const std::list<parser::EquivalenceObject> *> equivalenceSets;
621     // Names of all common block objects in the scope
622     std::set<SourceName> commonBlockObjects;
623     // Info about about SAVE statements and attributes in current scope
624     struct {
625       std::optional<SourceName> saveAll; // "SAVE" without entity list
626       std::set<SourceName> entities; // names of entities with save attr
627       std::set<SourceName> commons; // names of common blocks with save attr
628     } saveInfo;
629   } specPartState_;
630 
631 private:
632   Scope *currScope_{nullptr};
633 };
634 
635 class ModuleVisitor : public virtual ScopeHandler {
636 public:
637   bool Pre(const parser::AccessStmt &);
638   bool Pre(const parser::Only &);
639   bool Pre(const parser::Rename::Names &);
640   bool Pre(const parser::Rename::Operators &);
641   bool Pre(const parser::UseStmt &);
642   void Post(const parser::UseStmt &);
643 
644   void BeginModule(const parser::Name &, bool isSubmodule);
645   bool BeginSubmodule(const parser::Name &, const parser::ParentIdentifier &);
646   void ApplyDefaultAccess();
647   void AddGenericUse(GenericDetails &, const SourceName &, const Symbol &);
648   void AddAndCheckExplicitIntrinsicUse(SourceName, bool isIntrinsic);
649   void ClearUseRenames() { useRenames_.clear(); }
650   void ClearUseOnly() { useOnly_.clear(); }
651   void ClearExplicitIntrinsicUses() {
652     explicitIntrinsicUses_.clear();
653     explicitNonIntrinsicUses_.clear();
654   }
655 
656 private:
657   // The default access spec for this module.
658   Attr defaultAccess_{Attr::PUBLIC};
659   // The location of the last AccessStmt without access-ids, if any.
660   std::optional<SourceName> prevAccessStmt_;
661   // The scope of the module during a UseStmt
662   Scope *useModuleScope_{nullptr};
663   // Names that have appeared in a rename clause of a USE statement
664   std::set<std::pair<SourceName, Scope *>> useRenames_;
665   // Names that have appeared in an ONLY clause of a USE statement
666   std::set<std::pair<SourceName, Scope *>> useOnly_;
667   // Module names that have appeared in USE statements with explicit
668   // INTRINSIC or NON_INTRINSIC keywords
669   std::set<SourceName> explicitIntrinsicUses_;
670   std::set<SourceName> explicitNonIntrinsicUses_;
671 
672   Symbol &SetAccess(const SourceName &, Attr attr, Symbol * = nullptr);
673   // A rename in a USE statement: local => use
674   struct SymbolRename {
675     Symbol *local{nullptr};
676     Symbol *use{nullptr};
677   };
678   // Record a use from useModuleScope_ of use Name/Symbol as local Name/Symbol
679   SymbolRename AddUse(const SourceName &localName, const SourceName &useName);
680   SymbolRename AddUse(const SourceName &, const SourceName &, Symbol *);
681   void DoAddUse(const SourceName &, const SourceName &, Symbol &localSymbol,
682       const Symbol &useSymbol);
683   void AddUse(const GenericSpecInfo &);
684   // If appropriate, erase a previously USE-associated symbol
685   void EraseRenamedSymbol(const Symbol &);
686   // Record a name appearing in a USE rename clause
687   void AddUseRename(const SourceName &name) {
688     useRenames_.emplace(std::make_pair(name, useModuleScope_));
689   }
690   bool IsUseRenamed(const SourceName &name) const {
691     return useRenames_.find({name, useModuleScope_}) != useRenames_.end();
692   }
693   // Record a name appearing in a USE ONLY clause
694   void AddUseOnly(const SourceName &name) {
695     useOnly_.emplace(std::make_pair(name, useModuleScope_));
696   }
697   bool IsUseOnly(const SourceName &name) const {
698     return useOnly_.find({name, useModuleScope_}) != useOnly_.end();
699   }
700   Scope *FindModule(const parser::Name &, std::optional<bool> isIntrinsic,
701       Scope *ancestor = nullptr);
702 };
703 
704 class InterfaceVisitor : public virtual ScopeHandler {
705 public:
706   bool Pre(const parser::InterfaceStmt &);
707   void Post(const parser::InterfaceStmt &);
708   void Post(const parser::EndInterfaceStmt &);
709   bool Pre(const parser::GenericSpec &);
710   bool Pre(const parser::ProcedureStmt &);
711   bool Pre(const parser::GenericStmt &);
712   void Post(const parser::GenericStmt &);
713 
714   bool inInterfaceBlock() const;
715   bool isGeneric() const;
716   bool isAbstract() const;
717 
718 protected:
719   Symbol &GetGenericSymbol() {
720     return DEREF(genericInfo_.top().symbol);
721   }
722   // Add to generic the symbol for the subprogram with the same name
723   void CheckGenericProcedures(Symbol &);
724 
725 private:
726   // A new GenericInfo is pushed for each interface block and generic stmt
727   struct GenericInfo {
728     GenericInfo(bool isInterface, bool isAbstract = false)
729         : isInterface{isInterface}, isAbstract{isAbstract} {}
730     bool isInterface; // in interface block
731     bool isAbstract; // in abstract interface block
732     Symbol *symbol{nullptr}; // the generic symbol being defined
733   };
734   std::stack<GenericInfo> genericInfo_;
735   const GenericInfo &GetGenericInfo() const { return genericInfo_.top(); }
736   void SetGenericSymbol(Symbol &symbol) { genericInfo_.top().symbol = &symbol; }
737 
738   using ProcedureKind = parser::ProcedureStmt::Kind;
739   // mapping of generic to its specific proc names and kinds
740   std::multimap<Symbol *, std::pair<const parser::Name *, ProcedureKind>>
741       specificProcs_;
742 
743   void AddSpecificProcs(const std::list<parser::Name> &, ProcedureKind);
744   void ResolveSpecificsInGeneric(Symbol &generic);
745 };
746 
747 class SubprogramVisitor : public virtual ScopeHandler, public InterfaceVisitor {
748 public:
749   ~SubprogramVisitor();
750   bool HandleStmtFunction(const parser::StmtFunctionStmt &);
751   bool Pre(const parser::SubroutineStmt &);
752   void Post(const parser::SubroutineStmt &);
753   bool Pre(const parser::FunctionStmt &);
754   void Post(const parser::FunctionStmt &);
755   bool Pre(const parser::EntryStmt &);
756   void Post(const parser::EntryStmt &);
757   bool Pre(const parser::InterfaceBody::Subroutine &);
758   void Post(const parser::InterfaceBody::Subroutine &);
759   bool Pre(const parser::InterfaceBody::Function &);
760   void Post(const parser::InterfaceBody::Function &);
761   bool Pre(const parser::Suffix &);
762   bool Pre(const parser::PrefixSpec &);
763 
764   bool BeginSubprogram(
765       const parser::Name &, Symbol::Flag, bool hasModulePrefix = false);
766   bool BeginMpSubprogram(const parser::Name &);
767   void PushBlockDataScope(const parser::Name &);
768   void EndSubprogram();
769 
770 protected:
771   void FinishFunctionResult();
772   // Set when we see a stmt function that is really an array element assignment
773   bool badStmtFuncFound_{false};
774 
775 private:
776   // Info about the current function: parse tree of the type in the PrefixSpec;
777   // name and symbol of the function result from the Suffix; source location.
778   struct FuncInfo {
779     const parser::DeclarationTypeSpec *parsedType{nullptr};
780     const parser::Name *resultName{nullptr};
781     Symbol *resultSymbol{nullptr};
782     std::optional<SourceName> source;
783     bool inFunctionStmt{false}; // true between Pre/Post of FunctionStmt
784   };
785   std::vector<FuncInfo> funcInfoStack_;
786 
787   // Edits an existing symbol created for earlier calls to a subprogram or ENTRY
788   // so that it can be replaced by a later definition.
789   bool HandlePreviousCalls(const parser::Name &, Symbol &, Symbol::Flag);
790   void CheckExtantProc(const parser::Name &, Symbol::Flag);
791   // Create a subprogram symbol in the current scope and push a new scope.
792   Symbol &PushSubprogramScope(const parser::Name &, Symbol::Flag);
793   Symbol *GetSpecificFromGeneric(const parser::Name &);
794   SubprogramDetails &PostSubprogramStmt(const parser::Name &);
795 };
796 
797 class DeclarationVisitor : public ArraySpecVisitor,
798                            public virtual ScopeHandler {
799 public:
800   using ArraySpecVisitor::Post;
801   using ScopeHandler::Post;
802   using ScopeHandler::Pre;
803 
804   bool Pre(const parser::Initialization &);
805   void Post(const parser::EntityDecl &);
806   void Post(const parser::ObjectDecl &);
807   void Post(const parser::PointerDecl &);
808   bool Pre(const parser::BindStmt &) { return BeginAttrs(); }
809   void Post(const parser::BindStmt &) { EndAttrs(); }
810   bool Pre(const parser::BindEntity &);
811   bool Pre(const parser::OldParameterStmt &);
812   bool Pre(const parser::NamedConstantDef &);
813   bool Pre(const parser::NamedConstant &);
814   void Post(const parser::EnumDef &);
815   bool Pre(const parser::Enumerator &);
816   bool Pre(const parser::AccessSpec &);
817   bool Pre(const parser::AsynchronousStmt &);
818   bool Pre(const parser::ContiguousStmt &);
819   bool Pre(const parser::ExternalStmt &);
820   bool Pre(const parser::IntentStmt &);
821   bool Pre(const parser::IntrinsicStmt &);
822   bool Pre(const parser::OptionalStmt &);
823   bool Pre(const parser::ProtectedStmt &);
824   bool Pre(const parser::ValueStmt &);
825   bool Pre(const parser::VolatileStmt &);
826   bool Pre(const parser::AllocatableStmt &) {
827     objectDeclAttr_ = Attr::ALLOCATABLE;
828     return true;
829   }
830   void Post(const parser::AllocatableStmt &) { objectDeclAttr_ = std::nullopt; }
831   bool Pre(const parser::TargetStmt &) {
832     objectDeclAttr_ = Attr::TARGET;
833     return true;
834   }
835   void Post(const parser::TargetStmt &) { objectDeclAttr_ = std::nullopt; }
836   void Post(const parser::DimensionStmt::Declaration &);
837   void Post(const parser::CodimensionDecl &);
838   bool Pre(const parser::TypeDeclarationStmt &) { return BeginDecl(); }
839   void Post(const parser::TypeDeclarationStmt &);
840   void Post(const parser::IntegerTypeSpec &);
841   void Post(const parser::IntrinsicTypeSpec::Real &);
842   void Post(const parser::IntrinsicTypeSpec::Complex &);
843   void Post(const parser::IntrinsicTypeSpec::Logical &);
844   void Post(const parser::IntrinsicTypeSpec::Character &);
845   void Post(const parser::CharSelector::LengthAndKind &);
846   void Post(const parser::CharLength &);
847   void Post(const parser::LengthSelector &);
848   bool Pre(const parser::KindParam &);
849   bool Pre(const parser::DeclarationTypeSpec::Type &);
850   void Post(const parser::DeclarationTypeSpec::Type &);
851   bool Pre(const parser::DeclarationTypeSpec::Class &);
852   void Post(const parser::DeclarationTypeSpec::Class &);
853   void Post(const parser::DeclarationTypeSpec::Record &);
854   void Post(const parser::DerivedTypeSpec &);
855   bool Pre(const parser::DerivedTypeDef &);
856   bool Pre(const parser::DerivedTypeStmt &);
857   void Post(const parser::DerivedTypeStmt &);
858   bool Pre(const parser::TypeParamDefStmt &) { return BeginDecl(); }
859   void Post(const parser::TypeParamDefStmt &);
860   bool Pre(const parser::TypeAttrSpec::Extends &);
861   bool Pre(const parser::PrivateStmt &);
862   bool Pre(const parser::SequenceStmt &);
863   bool Pre(const parser::ComponentDefStmt &) { return BeginDecl(); }
864   void Post(const parser::ComponentDefStmt &) { EndDecl(); }
865   void Post(const parser::ComponentDecl &);
866   void Post(const parser::FillDecl &);
867   bool Pre(const parser::ProcedureDeclarationStmt &);
868   void Post(const parser::ProcedureDeclarationStmt &);
869   bool Pre(const parser::DataComponentDefStmt &); // returns false
870   bool Pre(const parser::ProcComponentDefStmt &);
871   void Post(const parser::ProcComponentDefStmt &);
872   bool Pre(const parser::ProcPointerInit &);
873   void Post(const parser::ProcInterface &);
874   void Post(const parser::ProcDecl &);
875   bool Pre(const parser::TypeBoundProcedurePart &);
876   void Post(const parser::TypeBoundProcedurePart &);
877   void Post(const parser::ContainsStmt &);
878   bool Pre(const parser::TypeBoundProcBinding &) { return BeginAttrs(); }
879   void Post(const parser::TypeBoundProcBinding &) { EndAttrs(); }
880   void Post(const parser::TypeBoundProcedureStmt::WithoutInterface &);
881   void Post(const parser::TypeBoundProcedureStmt::WithInterface &);
882   void Post(const parser::FinalProcedureStmt &);
883   bool Pre(const parser::TypeBoundGenericStmt &);
884   bool Pre(const parser::StructureDef &); // returns false
885   bool Pre(const parser::Union::UnionStmt &);
886   bool Pre(const parser::StructureField &);
887   void Post(const parser::StructureField &);
888   bool Pre(const parser::AllocateStmt &);
889   void Post(const parser::AllocateStmt &);
890   bool Pre(const parser::StructureConstructor &);
891   bool Pre(const parser::NamelistStmt::Group &);
892   bool Pre(const parser::IoControlSpec &);
893   bool Pre(const parser::CommonStmt::Block &);
894   bool Pre(const parser::CommonBlockObject &);
895   void Post(const parser::CommonBlockObject &);
896   bool Pre(const parser::EquivalenceStmt &);
897   bool Pre(const parser::SaveStmt &);
898   bool Pre(const parser::BasedPointerStmt &);
899 
900   void PointerInitialization(
901       const parser::Name &, const parser::InitialDataTarget &);
902   void PointerInitialization(
903       const parser::Name &, const parser::ProcPointerInit &);
904   void NonPointerInitialization(
905       const parser::Name &, const parser::ConstantExpr &);
906   void CheckExplicitInterface(const parser::Name &);
907   void CheckBindings(const parser::TypeBoundProcedureStmt::WithoutInterface &);
908 
909   const parser::Name *ResolveDesignator(const parser::Designator &);
910 
911 protected:
912   bool BeginDecl();
913   void EndDecl();
914   Symbol &DeclareObjectEntity(const parser::Name &, Attrs = Attrs{});
915   // Make sure that there's an entity in an enclosing scope called Name
916   Symbol &FindOrDeclareEnclosingEntity(const parser::Name &);
917   // Declare a LOCAL/LOCAL_INIT entity. If there isn't a type specified
918   // it comes from the entity in the containing scope, or implicit rules.
919   // Return pointer to the new symbol, or nullptr on error.
920   Symbol *DeclareLocalEntity(const parser::Name &);
921   // Declare a statement entity (i.e., an implied DO loop index for
922   // a DATA statement or an array constructor).  If there isn't an explict
923   // type specified, implicit rules apply. Return pointer to the new symbol,
924   // or nullptr on error.
925   Symbol *DeclareStatementEntity(const parser::DoVariable &,
926       const std::optional<parser::IntegerTypeSpec> &);
927   Symbol &MakeCommonBlockSymbol(const parser::Name &);
928   Symbol &MakeCommonBlockSymbol(const std::optional<parser::Name> &);
929   bool CheckUseError(const parser::Name &);
930   void CheckAccessibility(const SourceName &, bool, Symbol &);
931   void CheckCommonBlocks();
932   void CheckSaveStmts();
933   void CheckEquivalenceSets();
934   bool CheckNotInBlock(const char *);
935   bool NameIsKnownOrIntrinsic(const parser::Name &);
936 
937   // Each of these returns a pointer to a resolved Name (i.e. with symbol)
938   // or nullptr in case of error.
939   const parser::Name *ResolveStructureComponent(
940       const parser::StructureComponent &);
941   const parser::Name *ResolveDataRef(const parser::DataRef &);
942   const parser::Name *ResolveName(const parser::Name &);
943   bool PassesSharedLocalityChecks(const parser::Name &name, Symbol &symbol);
944   Symbol *NoteInterfaceName(const parser::Name &);
945   bool IsUplevelReference(const Symbol &);
946 
947   std::optional<SourceName> BeginCheckOnIndexUseInOwnBounds(
948       const parser::DoVariable &name) {
949     std::optional<SourceName> result{checkIndexUseInOwnBounds_};
950     checkIndexUseInOwnBounds_ = name.thing.thing.source;
951     return result;
952   }
953   void EndCheckOnIndexUseInOwnBounds(const std::optional<SourceName> &restore) {
954     checkIndexUseInOwnBounds_ = restore;
955   }
956 
957 private:
958   // The attribute corresponding to the statement containing an ObjectDecl
959   std::optional<Attr> objectDeclAttr_;
960   // Info about current character type while walking DeclTypeSpec.
961   // Also captures any "*length" specifier on an individual declaration.
962   struct {
963     std::optional<ParamValue> length;
964     std::optional<KindExpr> kind;
965   } charInfo_;
966   // Info about current derived type or STRUCTURE while walking
967   // DerivedTypeDef / StructureDef
968   struct {
969     const parser::Name *extends{nullptr}; // EXTENDS(name)
970     bool privateComps{false}; // components are private by default
971     bool privateBindings{false}; // bindings are private by default
972     bool sawContains{false}; // currently processing bindings
973     bool sequence{false}; // is a sequence type
974     const Symbol *type{nullptr}; // derived type being defined
975     bool isStructure{false}; // is a DEC STRUCTURE
976   } derivedTypeInfo_;
977   // In a ProcedureDeclarationStmt or ProcComponentDefStmt, this is
978   // the interface name, if any.
979   const parser::Name *interfaceName_{nullptr};
980   // Map type-bound generic to binding names of its specific bindings
981   std::multimap<Symbol *, const parser::Name *> genericBindings_;
982   // Info about current ENUM
983   struct EnumeratorState {
984     // Enum value must hold inside a C_INT (7.6.2).
985     std::optional<int> value{0};
986   } enumerationState_;
987   // Set for OldParameterStmt processing
988   bool inOldStyleParameterStmt_{false};
989   // Set when walking DATA & array constructor implied DO loop bounds
990   // to warn about use of the implied DO intex therein.
991   std::optional<SourceName> checkIndexUseInOwnBounds_;
992 
993   bool HandleAttributeStmt(Attr, const std::list<parser::Name> &);
994   Symbol &HandleAttributeStmt(Attr, const parser::Name &);
995   Symbol &DeclareUnknownEntity(const parser::Name &, Attrs);
996   Symbol &DeclareProcEntity(const parser::Name &, Attrs, const ProcInterface &);
997   void SetType(const parser::Name &, const DeclTypeSpec &);
998   std::optional<DerivedTypeSpec> ResolveDerivedType(const parser::Name &);
999   std::optional<DerivedTypeSpec> ResolveExtendsType(
1000       const parser::Name &, const parser::Name *);
1001   Symbol *MakeTypeSymbol(const SourceName &, Details &&);
1002   Symbol *MakeTypeSymbol(const parser::Name &, Details &&);
1003   bool OkToAddComponent(const parser::Name &, const Symbol * = nullptr);
1004   ParamValue GetParamValue(
1005       const parser::TypeParamValue &, common::TypeParamAttr attr);
1006   void CheckCommonBlockDerivedType(const SourceName &, const Symbol &);
1007   std::optional<MessageFixedText> CheckSaveAttr(const Symbol &);
1008   Attrs HandleSaveName(const SourceName &, Attrs);
1009   void AddSaveName(std::set<SourceName> &, const SourceName &);
1010   void SetSaveAttr(Symbol &);
1011   bool HandleUnrestrictedSpecificIntrinsicFunction(const parser::Name &);
1012   const parser::Name *FindComponent(const parser::Name *, const parser::Name &);
1013   void Initialization(const parser::Name &, const parser::Initialization &,
1014       bool inComponentDecl);
1015   bool PassesLocalityChecks(const parser::Name &name, Symbol &symbol);
1016   bool CheckForHostAssociatedImplicit(const parser::Name &);
1017 
1018   // Declare an object or procedure entity.
1019   // T is one of: EntityDetails, ObjectEntityDetails, ProcEntityDetails
1020   template <typename T>
1021   Symbol &DeclareEntity(const parser::Name &name, Attrs attrs) {
1022     Symbol &symbol{MakeSymbol(name, attrs)};
1023     if (context().HasError(symbol) || symbol.has<T>()) {
1024       return symbol; // OK or error already reported
1025     } else if (symbol.has<UnknownDetails>()) {
1026       symbol.set_details(T{});
1027       return symbol;
1028     } else if (auto *details{symbol.detailsIf<EntityDetails>()}) {
1029       symbol.set_details(T{std::move(*details)});
1030       return symbol;
1031     } else if (std::is_same_v<EntityDetails, T> &&
1032         (symbol.has<ObjectEntityDetails>() ||
1033             symbol.has<ProcEntityDetails>())) {
1034       return symbol; // OK
1035     } else if (auto *details{symbol.detailsIf<UseDetails>()}) {
1036       Say(name.source,
1037           "'%s' is use-associated from module '%s' and cannot be re-declared"_err_en_US,
1038           name.source, GetUsedModule(*details).name());
1039     } else if (auto *details{symbol.detailsIf<SubprogramNameDetails>()}) {
1040       if (details->kind() == SubprogramKind::Module) {
1041         Say2(name,
1042             "Declaration of '%s' conflicts with its use as module procedure"_err_en_US,
1043             symbol, "Module procedure definition"_en_US);
1044       } else if (details->kind() == SubprogramKind::Internal) {
1045         Say2(name,
1046             "Declaration of '%s' conflicts with its use as internal procedure"_err_en_US,
1047             symbol, "Internal procedure definition"_en_US);
1048       } else {
1049         DIE("unexpected kind");
1050       }
1051     } else if (std::is_same_v<ObjectEntityDetails, T> &&
1052         symbol.has<ProcEntityDetails>()) {
1053       SayWithDecl(
1054           name, symbol, "'%s' is already declared as a procedure"_err_en_US);
1055     } else if (std::is_same_v<ProcEntityDetails, T> &&
1056         symbol.has<ObjectEntityDetails>()) {
1057       if (InCommonBlock(symbol)) {
1058         SayWithDecl(name, symbol,
1059             "'%s' may not be a procedure as it is in a COMMON block"_err_en_US);
1060       } else {
1061         SayWithDecl(
1062             name, symbol, "'%s' is already declared as an object"_err_en_US);
1063       }
1064     } else if (!CheckPossibleBadForwardRef(symbol)) {
1065       SayAlreadyDeclared(name, symbol);
1066     }
1067     context().SetError(symbol);
1068     return symbol;
1069   }
1070   bool HasCycle(const Symbol &, const ProcInterface &);
1071 };
1072 
1073 // Resolve construct entities and statement entities.
1074 // Check that construct names don't conflict with other names.
1075 class ConstructVisitor : public virtual DeclarationVisitor {
1076 public:
1077   bool Pre(const parser::ConcurrentHeader &);
1078   bool Pre(const parser::LocalitySpec::Local &);
1079   bool Pre(const parser::LocalitySpec::LocalInit &);
1080   bool Pre(const parser::LocalitySpec::Shared &);
1081   bool Pre(const parser::AcSpec &);
1082   bool Pre(const parser::AcImpliedDo &);
1083   bool Pre(const parser::DataImpliedDo &);
1084   bool Pre(const parser::DataIDoObject &);
1085   bool Pre(const parser::DataStmtObject &);
1086   bool Pre(const parser::DataStmtValue &);
1087   bool Pre(const parser::DoConstruct &);
1088   void Post(const parser::DoConstruct &);
1089   bool Pre(const parser::ForallConstruct &);
1090   void Post(const parser::ForallConstruct &);
1091   bool Pre(const parser::ForallStmt &);
1092   void Post(const parser::ForallStmt &);
1093   bool Pre(const parser::BlockStmt &);
1094   bool Pre(const parser::EndBlockStmt &);
1095   void Post(const parser::Selector &);
1096   void Post(const parser::AssociateStmt &);
1097   void Post(const parser::EndAssociateStmt &);
1098   bool Pre(const parser::Association &);
1099   void Post(const parser::SelectTypeStmt &);
1100   void Post(const parser::SelectRankStmt &);
1101   bool Pre(const parser::SelectTypeConstruct &);
1102   void Post(const parser::SelectTypeConstruct &);
1103   bool Pre(const parser::SelectTypeConstruct::TypeCase &);
1104   void Post(const parser::SelectTypeConstruct::TypeCase &);
1105   // Creates Block scopes with neither symbol name nor symbol details.
1106   bool Pre(const parser::SelectRankConstruct::RankCase &);
1107   void Post(const parser::SelectRankConstruct::RankCase &);
1108   void Post(const parser::TypeGuardStmt::Guard &);
1109   void Post(const parser::SelectRankCaseStmt::Rank &);
1110   bool Pre(const parser::ChangeTeamStmt &);
1111   void Post(const parser::EndChangeTeamStmt &);
1112   void Post(const parser::CoarrayAssociation &);
1113 
1114   // Definitions of construct names
1115   bool Pre(const parser::WhereConstructStmt &x) { return CheckDef(x.t); }
1116   bool Pre(const parser::ForallConstructStmt &x) { return CheckDef(x.t); }
1117   bool Pre(const parser::CriticalStmt &x) { return CheckDef(x.t); }
1118   bool Pre(const parser::LabelDoStmt &) {
1119     return false; // error recovery
1120   }
1121   bool Pre(const parser::NonLabelDoStmt &x) { return CheckDef(x.t); }
1122   bool Pre(const parser::IfThenStmt &x) { return CheckDef(x.t); }
1123   bool Pre(const parser::SelectCaseStmt &x) { return CheckDef(x.t); }
1124   bool Pre(const parser::SelectRankConstruct &);
1125   void Post(const parser::SelectRankConstruct &);
1126   bool Pre(const parser::SelectRankStmt &x) {
1127     return CheckDef(std::get<0>(x.t));
1128   }
1129   bool Pre(const parser::SelectTypeStmt &x) {
1130     return CheckDef(std::get<0>(x.t));
1131   }
1132 
1133   // References to construct names
1134   void Post(const parser::MaskedElsewhereStmt &x) { CheckRef(x.t); }
1135   void Post(const parser::ElsewhereStmt &x) { CheckRef(x.v); }
1136   void Post(const parser::EndWhereStmt &x) { CheckRef(x.v); }
1137   void Post(const parser::EndForallStmt &x) { CheckRef(x.v); }
1138   void Post(const parser::EndCriticalStmt &x) { CheckRef(x.v); }
1139   void Post(const parser::EndDoStmt &x) { CheckRef(x.v); }
1140   void Post(const parser::ElseIfStmt &x) { CheckRef(x.t); }
1141   void Post(const parser::ElseStmt &x) { CheckRef(x.v); }
1142   void Post(const parser::EndIfStmt &x) { CheckRef(x.v); }
1143   void Post(const parser::CaseStmt &x) { CheckRef(x.t); }
1144   void Post(const parser::EndSelectStmt &x) { CheckRef(x.v); }
1145   void Post(const parser::SelectRankCaseStmt &x) { CheckRef(x.t); }
1146   void Post(const parser::TypeGuardStmt &x) { CheckRef(x.t); }
1147   void Post(const parser::CycleStmt &x) { CheckRef(x.v); }
1148   void Post(const parser::ExitStmt &x) { CheckRef(x.v); }
1149 
1150 private:
1151   // R1105 selector -> expr | variable
1152   // expr is set in either case unless there were errors
1153   struct Selector {
1154     Selector() {}
1155     Selector(const SourceName &source, MaybeExpr &&expr)
1156         : source{source}, expr{std::move(expr)} {}
1157     operator bool() const { return expr.has_value(); }
1158     parser::CharBlock source;
1159     MaybeExpr expr;
1160   };
1161   // association -> [associate-name =>] selector
1162   struct Association {
1163     const parser::Name *name{nullptr};
1164     Selector selector;
1165   };
1166   std::vector<Association> associationStack_;
1167   Association *currentAssociation_{nullptr};
1168 
1169   template <typename T> bool CheckDef(const T &t) {
1170     return CheckDef(std::get<std::optional<parser::Name>>(t));
1171   }
1172   template <typename T> void CheckRef(const T &t) {
1173     CheckRef(std::get<std::optional<parser::Name>>(t));
1174   }
1175   bool CheckDef(const std::optional<parser::Name> &);
1176   void CheckRef(const std::optional<parser::Name> &);
1177   const DeclTypeSpec &ToDeclTypeSpec(evaluate::DynamicType &&);
1178   const DeclTypeSpec &ToDeclTypeSpec(
1179       evaluate::DynamicType &&, MaybeSubscriptIntExpr &&length);
1180   Symbol *MakeAssocEntity();
1181   void SetTypeFromAssociation(Symbol &);
1182   void SetAttrsFromAssociation(Symbol &);
1183   Selector ResolveSelector(const parser::Selector &);
1184   void ResolveIndexName(const parser::ConcurrentControl &control);
1185   void SetCurrentAssociation(std::size_t n);
1186   Association &GetCurrentAssociation();
1187   void PushAssociation();
1188   void PopAssociation(std::size_t count = 1);
1189 };
1190 
1191 // Create scopes for OpenACC constructs
1192 class AccVisitor : public virtual DeclarationVisitor {
1193 public:
1194   void AddAccSourceRange(const parser::CharBlock &);
1195 
1196   static bool NeedsScope(const parser::OpenACCBlockConstruct &);
1197 
1198   bool Pre(const parser::OpenACCBlockConstruct &);
1199   void Post(const parser::OpenACCBlockConstruct &);
1200   bool Pre(const parser::AccBeginBlockDirective &x) {
1201     AddAccSourceRange(x.source);
1202     return true;
1203   }
1204   void Post(const parser::AccBeginBlockDirective &) {
1205     messageHandler().set_currStmtSource(std::nullopt);
1206   }
1207   bool Pre(const parser::AccEndBlockDirective &x) {
1208     AddAccSourceRange(x.source);
1209     return true;
1210   }
1211   void Post(const parser::AccEndBlockDirective &) {
1212     messageHandler().set_currStmtSource(std::nullopt);
1213   }
1214   bool Pre(const parser::AccBeginLoopDirective &x) {
1215     AddAccSourceRange(x.source);
1216     return true;
1217   }
1218   void Post(const parser::AccBeginLoopDirective &x) {
1219     messageHandler().set_currStmtSource(std::nullopt);
1220   }
1221 };
1222 
1223 bool AccVisitor::NeedsScope(const parser::OpenACCBlockConstruct &x) {
1224   const auto &beginBlockDir{std::get<parser::AccBeginBlockDirective>(x.t)};
1225   const auto &beginDir{std::get<parser::AccBlockDirective>(beginBlockDir.t)};
1226   switch (beginDir.v) {
1227   case llvm::acc::Directive::ACCD_data:
1228   case llvm::acc::Directive::ACCD_host_data:
1229   case llvm::acc::Directive::ACCD_kernels:
1230   case llvm::acc::Directive::ACCD_parallel:
1231   case llvm::acc::Directive::ACCD_serial:
1232     return true;
1233   default:
1234     return false;
1235   }
1236 }
1237 
1238 void AccVisitor::AddAccSourceRange(const parser::CharBlock &source) {
1239   messageHandler().set_currStmtSource(source);
1240   currScope().AddSourceRange(source);
1241 }
1242 
1243 bool AccVisitor::Pre(const parser::OpenACCBlockConstruct &x) {
1244   if (NeedsScope(x)) {
1245     PushScope(Scope::Kind::Block, nullptr);
1246   }
1247   return true;
1248 }
1249 
1250 void AccVisitor::Post(const parser::OpenACCBlockConstruct &x) {
1251   if (NeedsScope(x)) {
1252     PopScope();
1253   }
1254 }
1255 
1256 // Create scopes for OpenMP constructs
1257 class OmpVisitor : public virtual DeclarationVisitor {
1258 public:
1259   void AddOmpSourceRange(const parser::CharBlock &);
1260 
1261   static bool NeedsScope(const parser::OpenMPBlockConstruct &);
1262 
1263   bool Pre(const parser::OpenMPBlockConstruct &);
1264   void Post(const parser::OpenMPBlockConstruct &);
1265   bool Pre(const parser::OmpBeginBlockDirective &x) {
1266     AddOmpSourceRange(x.source);
1267     return true;
1268   }
1269   void Post(const parser::OmpBeginBlockDirective &) {
1270     messageHandler().set_currStmtSource(std::nullopt);
1271   }
1272   bool Pre(const parser::OmpEndBlockDirective &x) {
1273     AddOmpSourceRange(x.source);
1274     return true;
1275   }
1276   void Post(const parser::OmpEndBlockDirective &) {
1277     messageHandler().set_currStmtSource(std::nullopt);
1278   }
1279 
1280   bool Pre(const parser::OpenMPLoopConstruct &) {
1281     PushScope(Scope::Kind::Block, nullptr);
1282     return true;
1283   }
1284   void Post(const parser::OpenMPLoopConstruct &) { PopScope(); }
1285   bool Pre(const parser::OmpBeginLoopDirective &x) {
1286     AddOmpSourceRange(x.source);
1287     return true;
1288   }
1289   void Post(const parser::OmpBeginLoopDirective &) {
1290     messageHandler().set_currStmtSource(std::nullopt);
1291   }
1292   bool Pre(const parser::OmpEndLoopDirective &x) {
1293     AddOmpSourceRange(x.source);
1294     return true;
1295   }
1296   void Post(const parser::OmpEndLoopDirective &) {
1297     messageHandler().set_currStmtSource(std::nullopt);
1298   }
1299 
1300   bool Pre(const parser::OpenMPSectionsConstruct &) {
1301     PushScope(Scope::Kind::Block, nullptr);
1302     return true;
1303   }
1304   void Post(const parser::OpenMPSectionsConstruct &) { PopScope(); }
1305   bool Pre(const parser::OmpBeginSectionsDirective &x) {
1306     AddOmpSourceRange(x.source);
1307     return true;
1308   }
1309   void Post(const parser::OmpBeginSectionsDirective &) {
1310     messageHandler().set_currStmtSource(std::nullopt);
1311   }
1312   bool Pre(const parser::OmpEndSectionsDirective &x) {
1313     AddOmpSourceRange(x.source);
1314     return true;
1315   }
1316   void Post(const parser::OmpEndSectionsDirective &) {
1317     messageHandler().set_currStmtSource(std::nullopt);
1318   }
1319 };
1320 
1321 bool OmpVisitor::NeedsScope(const parser::OpenMPBlockConstruct &x) {
1322   const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)};
1323   const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
1324   switch (beginDir.v) {
1325   case llvm::omp::Directive::OMPD_target_data:
1326   case llvm::omp::Directive::OMPD_master:
1327   case llvm::omp::Directive::OMPD_ordered:
1328   case llvm::omp::Directive::OMPD_taskgroup:
1329     return false;
1330   default:
1331     return true;
1332   }
1333 }
1334 
1335 void OmpVisitor::AddOmpSourceRange(const parser::CharBlock &source) {
1336   messageHandler().set_currStmtSource(source);
1337   currScope().AddSourceRange(source);
1338 }
1339 
1340 bool OmpVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
1341   if (NeedsScope(x)) {
1342     PushScope(Scope::Kind::Block, nullptr);
1343   }
1344   return true;
1345 }
1346 
1347 void OmpVisitor::Post(const parser::OpenMPBlockConstruct &x) {
1348   if (NeedsScope(x)) {
1349     PopScope();
1350   }
1351 }
1352 
1353 // Walk the parse tree and resolve names to symbols.
1354 class ResolveNamesVisitor : public virtual ScopeHandler,
1355                             public ModuleVisitor,
1356                             public SubprogramVisitor,
1357                             public ConstructVisitor,
1358                             public OmpVisitor,
1359                             public AccVisitor {
1360 public:
1361   using AccVisitor::Post;
1362   using AccVisitor::Pre;
1363   using ArraySpecVisitor::Post;
1364   using ConstructVisitor::Post;
1365   using ConstructVisitor::Pre;
1366   using DeclarationVisitor::Post;
1367   using DeclarationVisitor::Pre;
1368   using ImplicitRulesVisitor::Post;
1369   using ImplicitRulesVisitor::Pre;
1370   using InterfaceVisitor::Post;
1371   using InterfaceVisitor::Pre;
1372   using ModuleVisitor::Post;
1373   using ModuleVisitor::Pre;
1374   using OmpVisitor::Post;
1375   using OmpVisitor::Pre;
1376   using ScopeHandler::Post;
1377   using ScopeHandler::Pre;
1378   using SubprogramVisitor::Post;
1379   using SubprogramVisitor::Pre;
1380 
1381   ResolveNamesVisitor(
1382       SemanticsContext &context, ImplicitRulesMap &rules, Scope &top)
1383       : BaseVisitor{context, *this, rules}, topScope_{top} {
1384     PushScope(top);
1385   }
1386 
1387   Scope &topScope() const { return topScope_; }
1388 
1389   // Default action for a parse tree node is to visit children.
1390   template <typename T> bool Pre(const T &) { return true; }
1391   template <typename T> void Post(const T &) {}
1392 
1393   bool Pre(const parser::SpecificationPart &);
1394   void Post(const parser::Program &);
1395   bool Pre(const parser::ImplicitStmt &);
1396   void Post(const parser::PointerObject &);
1397   void Post(const parser::AllocateObject &);
1398   bool Pre(const parser::PointerAssignmentStmt &);
1399   void Post(const parser::Designator &);
1400   template <typename A, typename B>
1401   void Post(const parser::LoopBounds<A, B> &x) {
1402     ResolveName(*parser::Unwrap<parser::Name>(x.name));
1403   }
1404   void Post(const parser::ProcComponentRef &);
1405   bool Pre(const parser::FunctionReference &);
1406   bool Pre(const parser::CallStmt &);
1407   bool Pre(const parser::ImportStmt &);
1408   void Post(const parser::TypeGuardStmt &);
1409   bool Pre(const parser::StmtFunctionStmt &);
1410   bool Pre(const parser::DefinedOpName &);
1411   bool Pre(const parser::ProgramUnit &);
1412   void Post(const parser::AssignStmt &);
1413   void Post(const parser::AssignedGotoStmt &);
1414 
1415   // These nodes should never be reached: they are handled in ProgramUnit
1416   bool Pre(const parser::MainProgram &) {
1417     llvm_unreachable("This node is handled in ProgramUnit");
1418   }
1419   bool Pre(const parser::FunctionSubprogram &) {
1420     llvm_unreachable("This node is handled in ProgramUnit");
1421   }
1422   bool Pre(const parser::SubroutineSubprogram &) {
1423     llvm_unreachable("This node is handled in ProgramUnit");
1424   }
1425   bool Pre(const parser::SeparateModuleSubprogram &) {
1426     llvm_unreachable("This node is handled in ProgramUnit");
1427   }
1428   bool Pre(const parser::Module &) {
1429     llvm_unreachable("This node is handled in ProgramUnit");
1430   }
1431   bool Pre(const parser::Submodule &) {
1432     llvm_unreachable("This node is handled in ProgramUnit");
1433   }
1434   bool Pre(const parser::BlockData &) {
1435     llvm_unreachable("This node is handled in ProgramUnit");
1436   }
1437 
1438   void NoteExecutablePartCall(Symbol::Flag, const parser::Call &);
1439 
1440   friend void ResolveSpecificationParts(SemanticsContext &, const Symbol &);
1441 
1442 private:
1443   // Kind of procedure we are expecting to see in a ProcedureDesignator
1444   std::optional<Symbol::Flag> expectedProcFlag_;
1445   std::optional<SourceName> prevImportStmt_;
1446   Scope &topScope_;
1447 
1448   void PreSpecificationConstruct(const parser::SpecificationConstruct &);
1449   void CreateCommonBlockSymbols(const parser::CommonStmt &);
1450   void CreateGeneric(const parser::GenericSpec &);
1451   void FinishSpecificationPart(const std::list<parser::DeclarationConstruct> &);
1452   void AnalyzeStmtFunctionStmt(const parser::StmtFunctionStmt &);
1453   void CheckImports();
1454   void CheckImport(const SourceName &, const SourceName &);
1455   void HandleCall(Symbol::Flag, const parser::Call &);
1456   void HandleProcedureName(Symbol::Flag, const parser::Name &);
1457   bool CheckImplicitNoneExternal(const SourceName &, const Symbol &);
1458   bool SetProcFlag(const parser::Name &, Symbol &, Symbol::Flag);
1459   void ResolveSpecificationParts(ProgramTree &);
1460   void AddSubpNames(ProgramTree &);
1461   bool BeginScopeForNode(const ProgramTree &);
1462   void EndScopeForNode(const ProgramTree &);
1463   void FinishSpecificationParts(const ProgramTree &);
1464   void FinishDerivedTypeInstantiation(Scope &);
1465   void ResolveExecutionParts(const ProgramTree &);
1466 };
1467 
1468 // ImplicitRules implementation
1469 
1470 bool ImplicitRules::isImplicitNoneType() const {
1471   if (isImplicitNoneType_) {
1472     return true;
1473   } else if (map_.empty() && inheritFromParent_) {
1474     return parent_->isImplicitNoneType();
1475   } else {
1476     return false; // default if not specified
1477   }
1478 }
1479 
1480 bool ImplicitRules::isImplicitNoneExternal() const {
1481   if (isImplicitNoneExternal_) {
1482     return true;
1483   } else if (inheritFromParent_) {
1484     return parent_->isImplicitNoneExternal();
1485   } else {
1486     return false; // default if not specified
1487   }
1488 }
1489 
1490 const DeclTypeSpec *ImplicitRules::GetType(
1491     SourceName name, bool respectImplicitNoneType) const {
1492   char ch{name.begin()[0]};
1493   if (isImplicitNoneType_ && respectImplicitNoneType) {
1494     return nullptr;
1495   } else if (auto it{map_.find(ch)}; it != map_.end()) {
1496     return &*it->second;
1497   } else if (inheritFromParent_) {
1498     return parent_->GetType(name, respectImplicitNoneType);
1499   } else if (ch >= 'i' && ch <= 'n') {
1500     return &context_.MakeNumericType(TypeCategory::Integer);
1501   } else if (ch >= 'a' && ch <= 'z') {
1502     return &context_.MakeNumericType(TypeCategory::Real);
1503   } else {
1504     return nullptr;
1505   }
1506 }
1507 
1508 void ImplicitRules::SetTypeMapping(const DeclTypeSpec &type,
1509     parser::Location fromLetter, parser::Location toLetter) {
1510   for (char ch = *fromLetter; ch; ch = ImplicitRules::Incr(ch)) {
1511     auto res{map_.emplace(ch, type)};
1512     if (!res.second) {
1513       context_.Say(parser::CharBlock{fromLetter},
1514           "More than one implicit type specified for '%c'"_err_en_US, ch);
1515     }
1516     if (ch == *toLetter) {
1517       break;
1518     }
1519   }
1520 }
1521 
1522 // Return the next char after ch in a way that works for ASCII or EBCDIC.
1523 // Return '\0' for the char after 'z'.
1524 char ImplicitRules::Incr(char ch) {
1525   switch (ch) {
1526   case 'i':
1527     return 'j';
1528   case 'r':
1529     return 's';
1530   case 'z':
1531     return '\0';
1532   default:
1533     return ch + 1;
1534   }
1535 }
1536 
1537 llvm::raw_ostream &operator<<(
1538     llvm::raw_ostream &o, const ImplicitRules &implicitRules) {
1539   o << "ImplicitRules:\n";
1540   for (char ch = 'a'; ch; ch = ImplicitRules::Incr(ch)) {
1541     ShowImplicitRule(o, implicitRules, ch);
1542   }
1543   ShowImplicitRule(o, implicitRules, '_');
1544   ShowImplicitRule(o, implicitRules, '$');
1545   ShowImplicitRule(o, implicitRules, '@');
1546   return o;
1547 }
1548 void ShowImplicitRule(
1549     llvm::raw_ostream &o, const ImplicitRules &implicitRules, char ch) {
1550   auto it{implicitRules.map_.find(ch)};
1551   if (it != implicitRules.map_.end()) {
1552     o << "  " << ch << ": " << *it->second << '\n';
1553   }
1554 }
1555 
1556 template <typename T> void BaseVisitor::Walk(const T &x) {
1557   parser::Walk(x, *this_);
1558 }
1559 
1560 void BaseVisitor::MakePlaceholder(
1561     const parser::Name &name, MiscDetails::Kind kind) {
1562   if (!name.symbol) {
1563     name.symbol = &context_->globalScope().MakeSymbol(
1564         name.source, Attrs{}, MiscDetails{kind});
1565   }
1566 }
1567 
1568 // AttrsVisitor implementation
1569 
1570 bool AttrsVisitor::BeginAttrs() {
1571   CHECK(!attrs_);
1572   attrs_ = std::make_optional<Attrs>();
1573   return true;
1574 }
1575 Attrs AttrsVisitor::GetAttrs() {
1576   CHECK(attrs_);
1577   return *attrs_;
1578 }
1579 Attrs AttrsVisitor::EndAttrs() {
1580   Attrs result{GetAttrs()};
1581   attrs_.reset();
1582   passName_ = std::nullopt;
1583   bindName_.reset();
1584   return result;
1585 }
1586 
1587 bool AttrsVisitor::SetPassNameOn(Symbol &symbol) {
1588   if (!passName_) {
1589     return false;
1590   }
1591   std::visit(common::visitors{
1592                  [&](ProcEntityDetails &x) { x.set_passName(*passName_); },
1593                  [&](ProcBindingDetails &x) { x.set_passName(*passName_); },
1594                  [](auto &) { common::die("unexpected pass name"); },
1595              },
1596       symbol.details());
1597   return true;
1598 }
1599 
1600 void AttrsVisitor::SetBindNameOn(Symbol &symbol) {
1601   if (!attrs_ || !attrs_->test(Attr::BIND_C)) {
1602     return;
1603   }
1604   std::optional<std::string> label{
1605       evaluate::GetScalarConstantValue<evaluate::Ascii>(bindName_)};
1606   // 18.9.2(2): discard leading and trailing blanks, ignore if all blank
1607   if (label) {
1608     auto first{label->find_first_not_of(" ")};
1609     if (first == std::string::npos) {
1610       // Empty NAME= means no binding at all (18.10.2p2)
1611       Say(currStmtSource().value(), "Blank binding label ignored"_warn_en_US);
1612       return;
1613     }
1614     auto last{label->find_last_not_of(" ")};
1615     label = label->substr(first, last - first + 1);
1616   } else {
1617     label = parser::ToLowerCaseLetters(symbol.name().ToString());
1618   }
1619   symbol.SetBindName(std::move(*label));
1620 }
1621 
1622 void AttrsVisitor::Post(const parser::LanguageBindingSpec &x) {
1623   CHECK(attrs_);
1624   if (CheckAndSet(Attr::BIND_C)) {
1625     if (x.v) {
1626       bindName_ = EvaluateExpr(*x.v);
1627     }
1628   }
1629 }
1630 bool AttrsVisitor::Pre(const parser::IntentSpec &x) {
1631   CHECK(attrs_);
1632   CheckAndSet(IntentSpecToAttr(x));
1633   return false;
1634 }
1635 bool AttrsVisitor::Pre(const parser::Pass &x) {
1636   if (CheckAndSet(Attr::PASS)) {
1637     if (x.v) {
1638       passName_ = x.v->source;
1639       MakePlaceholder(*x.v, MiscDetails::Kind::PassName);
1640     }
1641   }
1642   return false;
1643 }
1644 
1645 // C730, C743, C755, C778, C1543 say no attribute or prefix repetitions
1646 bool AttrsVisitor::IsDuplicateAttr(Attr attrName) {
1647   if (attrs_->test(attrName)) {
1648     Say(currStmtSource().value(),
1649         "Attribute '%s' cannot be used more than once"_warn_en_US,
1650         AttrToString(attrName));
1651     return true;
1652   }
1653   return false;
1654 }
1655 
1656 // See if attrName violates a constraint cause by a conflict.  attr1 and attr2
1657 // name attributes that cannot be used on the same declaration
1658 bool AttrsVisitor::HaveAttrConflict(Attr attrName, Attr attr1, Attr attr2) {
1659   if ((attrName == attr1 && attrs_->test(attr2)) ||
1660       (attrName == attr2 && attrs_->test(attr1))) {
1661     Say(currStmtSource().value(),
1662         "Attributes '%s' and '%s' conflict with each other"_err_en_US,
1663         AttrToString(attr1), AttrToString(attr2));
1664     return true;
1665   }
1666   return false;
1667 }
1668 // C759, C1543
1669 bool AttrsVisitor::IsConflictingAttr(Attr attrName) {
1670   return HaveAttrConflict(attrName, Attr::INTENT_IN, Attr::INTENT_INOUT) ||
1671       HaveAttrConflict(attrName, Attr::INTENT_IN, Attr::INTENT_OUT) ||
1672       HaveAttrConflict(attrName, Attr::INTENT_INOUT, Attr::INTENT_OUT) ||
1673       HaveAttrConflict(attrName, Attr::PASS, Attr::NOPASS) || // C781
1674       HaveAttrConflict(attrName, Attr::PURE, Attr::IMPURE) ||
1675       HaveAttrConflict(attrName, Attr::PUBLIC, Attr::PRIVATE) ||
1676       HaveAttrConflict(attrName, Attr::RECURSIVE, Attr::NON_RECURSIVE);
1677 }
1678 bool AttrsVisitor::CheckAndSet(Attr attrName) {
1679   CHECK(attrs_);
1680   if (IsConflictingAttr(attrName) || IsDuplicateAttr(attrName)) {
1681     return false;
1682   }
1683   attrs_->set(attrName);
1684   return true;
1685 }
1686 
1687 // DeclTypeSpecVisitor implementation
1688 
1689 const DeclTypeSpec *DeclTypeSpecVisitor::GetDeclTypeSpec() {
1690   return state_.declTypeSpec;
1691 }
1692 
1693 void DeclTypeSpecVisitor::BeginDeclTypeSpec() {
1694   CHECK(!state_.expectDeclTypeSpec);
1695   CHECK(!state_.declTypeSpec);
1696   state_.expectDeclTypeSpec = true;
1697 }
1698 void DeclTypeSpecVisitor::EndDeclTypeSpec() {
1699   CHECK(state_.expectDeclTypeSpec);
1700   state_ = {};
1701 }
1702 
1703 void DeclTypeSpecVisitor::SetDeclTypeSpecCategory(
1704     DeclTypeSpec::Category category) {
1705   CHECK(state_.expectDeclTypeSpec);
1706   state_.derived.category = category;
1707 }
1708 
1709 bool DeclTypeSpecVisitor::Pre(const parser::TypeGuardStmt &) {
1710   BeginDeclTypeSpec();
1711   return true;
1712 }
1713 void DeclTypeSpecVisitor::Post(const parser::TypeGuardStmt &) {
1714   EndDeclTypeSpec();
1715 }
1716 
1717 void DeclTypeSpecVisitor::Post(const parser::TypeSpec &typeSpec) {
1718   // Record the resolved DeclTypeSpec in the parse tree for use by
1719   // expression semantics if the DeclTypeSpec is a valid TypeSpec.
1720   // The grammar ensures that it's an intrinsic or derived type spec,
1721   // not TYPE(*) or CLASS(*) or CLASS(T).
1722   if (const DeclTypeSpec * spec{state_.declTypeSpec}) {
1723     switch (spec->category()) {
1724     case DeclTypeSpec::Numeric:
1725     case DeclTypeSpec::Logical:
1726     case DeclTypeSpec::Character:
1727       typeSpec.declTypeSpec = spec;
1728       break;
1729     case DeclTypeSpec::TypeDerived:
1730       if (const DerivedTypeSpec * derived{spec->AsDerived()}) {
1731         CheckForAbstractType(derived->typeSymbol()); // C703
1732         typeSpec.declTypeSpec = spec;
1733       }
1734       break;
1735     default:
1736       CRASH_NO_CASE;
1737     }
1738   }
1739 }
1740 
1741 void DeclTypeSpecVisitor::Post(
1742     const parser::IntrinsicTypeSpec::DoublePrecision &) {
1743   MakeNumericType(TypeCategory::Real, context().doublePrecisionKind());
1744 }
1745 void DeclTypeSpecVisitor::Post(
1746     const parser::IntrinsicTypeSpec::DoubleComplex &) {
1747   MakeNumericType(TypeCategory::Complex, context().doublePrecisionKind());
1748 }
1749 void DeclTypeSpecVisitor::MakeNumericType(TypeCategory category, int kind) {
1750   SetDeclTypeSpec(context().MakeNumericType(category, kind));
1751 }
1752 
1753 void DeclTypeSpecVisitor::CheckForAbstractType(const Symbol &typeSymbol) {
1754   if (typeSymbol.attrs().test(Attr::ABSTRACT)) {
1755     Say("ABSTRACT derived type may not be used here"_err_en_US);
1756   }
1757 }
1758 
1759 void DeclTypeSpecVisitor::Post(const parser::DeclarationTypeSpec::ClassStar &) {
1760   SetDeclTypeSpec(context().globalScope().MakeClassStarType());
1761 }
1762 void DeclTypeSpecVisitor::Post(const parser::DeclarationTypeSpec::TypeStar &) {
1763   SetDeclTypeSpec(context().globalScope().MakeTypeStarType());
1764 }
1765 
1766 // Check that we're expecting to see a DeclTypeSpec (and haven't seen one yet)
1767 // and save it in state_.declTypeSpec.
1768 void DeclTypeSpecVisitor::SetDeclTypeSpec(const DeclTypeSpec &declTypeSpec) {
1769   CHECK(state_.expectDeclTypeSpec);
1770   CHECK(!state_.declTypeSpec);
1771   state_.declTypeSpec = &declTypeSpec;
1772 }
1773 
1774 KindExpr DeclTypeSpecVisitor::GetKindParamExpr(
1775     TypeCategory category, const std::optional<parser::KindSelector> &kind) {
1776   return AnalyzeKindSelector(context(), category, kind);
1777 }
1778 
1779 // MessageHandler implementation
1780 
1781 Message &MessageHandler::Say(MessageFixedText &&msg) {
1782   return context_->Say(currStmtSource().value(), std::move(msg));
1783 }
1784 Message &MessageHandler::Say(MessageFormattedText &&msg) {
1785   return context_->Say(currStmtSource().value(), std::move(msg));
1786 }
1787 Message &MessageHandler::Say(const SourceName &name, MessageFixedText &&msg) {
1788   return Say(name, std::move(msg), name);
1789 }
1790 
1791 // ImplicitRulesVisitor implementation
1792 
1793 void ImplicitRulesVisitor::Post(const parser::ParameterStmt &) {
1794   prevParameterStmt_ = currStmtSource();
1795 }
1796 
1797 bool ImplicitRulesVisitor::Pre(const parser::ImplicitStmt &x) {
1798   bool result{
1799       std::visit(common::visitors{
1800                      [&](const std::list<ImplicitNoneNameSpec> &y) {
1801                        return HandleImplicitNone(y);
1802                      },
1803                      [&](const std::list<parser::ImplicitSpec> &) {
1804                        if (prevImplicitNoneType_) {
1805                          Say("IMPLICIT statement after IMPLICIT NONE or "
1806                              "IMPLICIT NONE(TYPE) statement"_err_en_US);
1807                          return false;
1808                        }
1809                        implicitRules_->set_isImplicitNoneType(false);
1810                        return true;
1811                      },
1812                  },
1813           x.u)};
1814   prevImplicit_ = currStmtSource();
1815   return result;
1816 }
1817 
1818 bool ImplicitRulesVisitor::Pre(const parser::LetterSpec &x) {
1819   auto loLoc{std::get<parser::Location>(x.t)};
1820   auto hiLoc{loLoc};
1821   if (auto hiLocOpt{std::get<std::optional<parser::Location>>(x.t)}) {
1822     hiLoc = *hiLocOpt;
1823     if (*hiLoc < *loLoc) {
1824       Say(hiLoc, "'%s' does not follow '%s' alphabetically"_err_en_US,
1825           std::string(hiLoc, 1), std::string(loLoc, 1));
1826       return false;
1827     }
1828   }
1829   implicitRules_->SetTypeMapping(*GetDeclTypeSpec(), loLoc, hiLoc);
1830   return false;
1831 }
1832 
1833 bool ImplicitRulesVisitor::Pre(const parser::ImplicitSpec &) {
1834   BeginDeclTypeSpec();
1835   set_allowForwardReferenceToDerivedType(true);
1836   return true;
1837 }
1838 
1839 void ImplicitRulesVisitor::Post(const parser::ImplicitSpec &) {
1840   EndDeclTypeSpec();
1841 }
1842 
1843 void ImplicitRulesVisitor::SetScope(const Scope &scope) {
1844   implicitRules_ = &DEREF(implicitRulesMap_).at(&scope);
1845   prevImplicit_ = std::nullopt;
1846   prevImplicitNone_ = std::nullopt;
1847   prevImplicitNoneType_ = std::nullopt;
1848   prevParameterStmt_ = std::nullopt;
1849 }
1850 void ImplicitRulesVisitor::BeginScope(const Scope &scope) {
1851   // find or create implicit rules for this scope
1852   DEREF(implicitRulesMap_).try_emplace(&scope, context(), implicitRules_);
1853   SetScope(scope);
1854 }
1855 
1856 // TODO: for all of these errors, reference previous statement too
1857 bool ImplicitRulesVisitor::HandleImplicitNone(
1858     const std::list<ImplicitNoneNameSpec> &nameSpecs) {
1859   if (prevImplicitNone_) {
1860     Say("More than one IMPLICIT NONE statement"_err_en_US);
1861     Say(*prevImplicitNone_, "Previous IMPLICIT NONE statement"_en_US);
1862     return false;
1863   }
1864   if (prevParameterStmt_) {
1865     Say("IMPLICIT NONE statement after PARAMETER statement"_err_en_US);
1866     return false;
1867   }
1868   prevImplicitNone_ = currStmtSource();
1869   bool implicitNoneTypeNever{
1870       context().IsEnabled(common::LanguageFeature::ImplicitNoneTypeNever)};
1871   if (nameSpecs.empty()) {
1872     if (!implicitNoneTypeNever) {
1873       prevImplicitNoneType_ = currStmtSource();
1874       implicitRules_->set_isImplicitNoneType(true);
1875       if (prevImplicit_) {
1876         Say("IMPLICIT NONE statement after IMPLICIT statement"_err_en_US);
1877         return false;
1878       }
1879     }
1880   } else {
1881     int sawType{0};
1882     int sawExternal{0};
1883     for (const auto noneSpec : nameSpecs) {
1884       switch (noneSpec) {
1885       case ImplicitNoneNameSpec::External:
1886         implicitRules_->set_isImplicitNoneExternal(true);
1887         ++sawExternal;
1888         break;
1889       case ImplicitNoneNameSpec::Type:
1890         if (!implicitNoneTypeNever) {
1891           prevImplicitNoneType_ = currStmtSource();
1892           implicitRules_->set_isImplicitNoneType(true);
1893           if (prevImplicit_) {
1894             Say("IMPLICIT NONE(TYPE) after IMPLICIT statement"_err_en_US);
1895             return false;
1896           }
1897           ++sawType;
1898         }
1899         break;
1900       }
1901     }
1902     if (sawType > 1) {
1903       Say("TYPE specified more than once in IMPLICIT NONE statement"_err_en_US);
1904       return false;
1905     }
1906     if (sawExternal > 1) {
1907       Say("EXTERNAL specified more than once in IMPLICIT NONE statement"_err_en_US);
1908       return false;
1909     }
1910   }
1911   return true;
1912 }
1913 
1914 // ArraySpecVisitor implementation
1915 
1916 void ArraySpecVisitor::Post(const parser::ArraySpec &x) {
1917   CHECK(arraySpec_.empty());
1918   arraySpec_ = AnalyzeArraySpec(context(), x);
1919 }
1920 void ArraySpecVisitor::Post(const parser::ComponentArraySpec &x) {
1921   CHECK(arraySpec_.empty());
1922   arraySpec_ = AnalyzeArraySpec(context(), x);
1923 }
1924 void ArraySpecVisitor::Post(const parser::CoarraySpec &x) {
1925   CHECK(coarraySpec_.empty());
1926   coarraySpec_ = AnalyzeCoarraySpec(context(), x);
1927 }
1928 
1929 const ArraySpec &ArraySpecVisitor::arraySpec() {
1930   return !arraySpec_.empty() ? arraySpec_ : attrArraySpec_;
1931 }
1932 const ArraySpec &ArraySpecVisitor::coarraySpec() {
1933   return !coarraySpec_.empty() ? coarraySpec_ : attrCoarraySpec_;
1934 }
1935 void ArraySpecVisitor::BeginArraySpec() {
1936   CHECK(arraySpec_.empty());
1937   CHECK(coarraySpec_.empty());
1938   CHECK(attrArraySpec_.empty());
1939   CHECK(attrCoarraySpec_.empty());
1940 }
1941 void ArraySpecVisitor::EndArraySpec() {
1942   CHECK(arraySpec_.empty());
1943   CHECK(coarraySpec_.empty());
1944   attrArraySpec_.clear();
1945   attrCoarraySpec_.clear();
1946 }
1947 void ArraySpecVisitor::PostAttrSpec() {
1948   // Save dimension/codimension from attrs so we can process array/coarray-spec
1949   // on the entity-decl
1950   if (!arraySpec_.empty()) {
1951     if (attrArraySpec_.empty()) {
1952       attrArraySpec_ = arraySpec_;
1953       arraySpec_.clear();
1954     } else {
1955       Say(currStmtSource().value(),
1956           "Attribute 'DIMENSION' cannot be used more than once"_err_en_US);
1957     }
1958   }
1959   if (!coarraySpec_.empty()) {
1960     if (attrCoarraySpec_.empty()) {
1961       attrCoarraySpec_ = coarraySpec_;
1962       coarraySpec_.clear();
1963     } else {
1964       Say(currStmtSource().value(),
1965           "Attribute 'CODIMENSION' cannot be used more than once"_err_en_US);
1966     }
1967   }
1968 }
1969 
1970 // ScopeHandler implementation
1971 
1972 void ScopeHandler::SayAlreadyDeclared(const parser::Name &name, Symbol &prev) {
1973   SayAlreadyDeclared(name.source, prev);
1974 }
1975 void ScopeHandler::SayAlreadyDeclared(const SourceName &name, Symbol &prev) {
1976   if (context().HasError(prev)) {
1977     // don't report another error about prev
1978   } else {
1979     if (const auto *details{prev.detailsIf<UseDetails>()}) {
1980       Say(name, "'%s' is already declared in this scoping unit"_err_en_US)
1981           .Attach(details->location(),
1982               "It is use-associated with '%s' in module '%s'"_err_en_US,
1983               details->symbol().name(), GetUsedModule(*details).name());
1984     } else {
1985       SayAlreadyDeclared(name, prev.name());
1986     }
1987     context().SetError(prev);
1988   }
1989 }
1990 void ScopeHandler::SayAlreadyDeclared(
1991     const SourceName &name1, const SourceName &name2) {
1992   if (name1.begin() < name2.begin()) {
1993     SayAlreadyDeclared(name2, name1);
1994   } else {
1995     Say(name1, "'%s' is already declared in this scoping unit"_err_en_US)
1996         .Attach(name2, "Previous declaration of '%s'"_en_US, name2);
1997   }
1998 }
1999 
2000 void ScopeHandler::SayWithReason(const parser::Name &name, Symbol &symbol,
2001     MessageFixedText &&msg1, MessageFixedText &&msg2) {
2002   Say2(name, std::move(msg1), symbol, std::move(msg2));
2003   context().SetError(symbol, msg1.isFatal());
2004 }
2005 
2006 void ScopeHandler::SayWithDecl(
2007     const parser::Name &name, Symbol &symbol, MessageFixedText &&msg) {
2008   SayWithReason(name, symbol, std::move(msg),
2009       symbol.test(Symbol::Flag::Implicit) ? "Implicit declaration of '%s'"_en_US
2010                                           : "Declaration of '%s'"_en_US);
2011 }
2012 
2013 void ScopeHandler::SayLocalMustBeVariable(
2014     const parser::Name &name, Symbol &symbol) {
2015   SayWithDecl(name, symbol,
2016       "The name '%s' must be a variable to appear"
2017       " in a locality-spec"_err_en_US);
2018 }
2019 
2020 void ScopeHandler::SayDerivedType(
2021     const SourceName &name, MessageFixedText &&msg, const Scope &type) {
2022   const Symbol &typeSymbol{DEREF(type.GetSymbol())};
2023   Say(name, std::move(msg), name, typeSymbol.name())
2024       .Attach(typeSymbol.name(), "Declaration of derived type '%s'"_en_US,
2025           typeSymbol.name());
2026 }
2027 void ScopeHandler::Say2(const SourceName &name1, MessageFixedText &&msg1,
2028     const SourceName &name2, MessageFixedText &&msg2) {
2029   Say(name1, std::move(msg1)).Attach(name2, std::move(msg2), name2);
2030 }
2031 void ScopeHandler::Say2(const SourceName &name, MessageFixedText &&msg1,
2032     Symbol &symbol, MessageFixedText &&msg2) {
2033   Say2(name, std::move(msg1), symbol.name(), std::move(msg2));
2034   context().SetError(symbol, msg1.isFatal());
2035 }
2036 void ScopeHandler::Say2(const parser::Name &name, MessageFixedText &&msg1,
2037     Symbol &symbol, MessageFixedText &&msg2) {
2038   Say2(name.source, std::move(msg1), symbol.name(), std::move(msg2));
2039   context().SetError(symbol, msg1.isFatal());
2040 }
2041 
2042 // This is essentially GetProgramUnitContaining(), but it can return
2043 // a mutable Scope &, it ignores statement functions, and it fails
2044 // gracefully for error recovery (returning the original Scope).
2045 template <typename T> static T &GetInclusiveScope(T &scope) {
2046   for (T *s{&scope}; !s->IsGlobal(); s = &s->parent()) {
2047     switch (s->kind()) {
2048     case Scope::Kind::Module:
2049     case Scope::Kind::MainProgram:
2050     case Scope::Kind::Subprogram:
2051     case Scope::Kind::BlockData:
2052       if (!s->IsStmtFunction()) {
2053         return *s;
2054       }
2055       break;
2056     default:;
2057     }
2058   }
2059   return scope;
2060 }
2061 
2062 Scope &ScopeHandler::InclusiveScope() { return GetInclusiveScope(currScope()); }
2063 
2064 Scope *ScopeHandler::GetHostProcedure() {
2065   Scope &parent{InclusiveScope().parent()};
2066   switch (parent.kind()) {
2067   case Scope::Kind::Subprogram:
2068     return &parent;
2069   case Scope::Kind::MainProgram:
2070     return &parent;
2071   default:
2072     return nullptr;
2073   }
2074 }
2075 
2076 Scope &ScopeHandler::NonDerivedTypeScope() {
2077   return currScope_->IsDerivedType() ? currScope_->parent() : *currScope_;
2078 }
2079 
2080 void ScopeHandler::PushScope(Scope::Kind kind, Symbol *symbol) {
2081   PushScope(currScope().MakeScope(kind, symbol));
2082 }
2083 void ScopeHandler::PushScope(Scope &scope) {
2084   currScope_ = &scope;
2085   auto kind{currScope_->kind()};
2086   if (kind != Scope::Kind::Block) {
2087     BeginScope(scope);
2088   }
2089   // The name of a module or submodule cannot be "used" in its scope,
2090   // as we read 19.3.1(2), so we allow the name to be used as a local
2091   // identifier in the module or submodule too.  Same with programs
2092   // (14.1(3)) and BLOCK DATA.
2093   if (!currScope_->IsDerivedType() && kind != Scope::Kind::Module &&
2094       kind != Scope::Kind::MainProgram && kind != Scope::Kind::BlockData) {
2095     if (auto *symbol{scope.symbol()}) {
2096       // Create a dummy symbol so we can't create another one with the same
2097       // name. It might already be there if we previously pushed the scope.
2098       if (!FindInScope(scope, symbol->name())) {
2099         auto &newSymbol{MakeSymbol(symbol->name())};
2100         if (kind == Scope::Kind::Subprogram) {
2101           // Allow for recursive references.  If this symbol is a function
2102           // without an explicit RESULT(), this new symbol will be discarded
2103           // and replaced with an object of the same name.
2104           newSymbol.set_details(HostAssocDetails{*symbol});
2105         } else {
2106           newSymbol.set_details(MiscDetails{MiscDetails::Kind::ScopeName});
2107         }
2108       }
2109     }
2110   }
2111 }
2112 void ScopeHandler::PopScope() {
2113   // Entities that are not yet classified as objects or procedures are now
2114   // assumed to be objects.
2115   // TODO: Statement functions
2116   for (auto &pair : currScope()) {
2117     ConvertToObjectEntity(*pair.second);
2118   }
2119   SetScope(currScope_->parent());
2120 }
2121 void ScopeHandler::SetScope(Scope &scope) {
2122   currScope_ = &scope;
2123   ImplicitRulesVisitor::SetScope(InclusiveScope());
2124 }
2125 
2126 Symbol *ScopeHandler::FindSymbol(const parser::Name &name) {
2127   return FindSymbol(currScope(), name);
2128 }
2129 Symbol *ScopeHandler::FindSymbol(const Scope &scope, const parser::Name &name) {
2130   if (scope.IsDerivedType()) {
2131     if (Symbol * symbol{scope.FindComponent(name.source)}) {
2132       if (!symbol->has<ProcBindingDetails>() &&
2133           !symbol->test(Symbol::Flag::ParentComp)) {
2134         return Resolve(name, symbol);
2135       }
2136     }
2137     return FindSymbol(scope.parent(), name);
2138   } else {
2139     // In EQUIVALENCE statements only resolve names in the local scope, see
2140     // 19.5.1.4, paragraph 2, item (10)
2141     return Resolve(name,
2142         inEquivalenceStmt_ ? FindInScope(scope, name)
2143                            : scope.FindSymbol(name.source));
2144   }
2145 }
2146 
2147 Symbol &ScopeHandler::MakeSymbol(
2148     Scope &scope, const SourceName &name, Attrs attrs) {
2149   if (Symbol * symbol{FindInScope(scope, name)}) {
2150     symbol->attrs() |= attrs;
2151     return *symbol;
2152   } else {
2153     const auto pair{scope.try_emplace(name, attrs, UnknownDetails{})};
2154     CHECK(pair.second); // name was not found, so must be able to add
2155     return *pair.first->second;
2156   }
2157 }
2158 Symbol &ScopeHandler::MakeSymbol(const SourceName &name, Attrs attrs) {
2159   return MakeSymbol(currScope(), name, attrs);
2160 }
2161 Symbol &ScopeHandler::MakeSymbol(const parser::Name &name, Attrs attrs) {
2162   return Resolve(name, MakeSymbol(name.source, attrs));
2163 }
2164 Symbol &ScopeHandler::MakeHostAssocSymbol(
2165     const parser::Name &name, const Symbol &hostSymbol) {
2166   Symbol &symbol{*NonDerivedTypeScope()
2167                       .try_emplace(name.source, HostAssocDetails{hostSymbol})
2168                       .first->second};
2169   name.symbol = &symbol;
2170   symbol.attrs() = hostSymbol.attrs(); // TODO: except PRIVATE, PUBLIC?
2171   symbol.flags() = hostSymbol.flags();
2172   return symbol;
2173 }
2174 Symbol &ScopeHandler::CopySymbol(const SourceName &name, const Symbol &symbol) {
2175   CHECK(!FindInScope(name));
2176   return MakeSymbol(currScope(), name, symbol.attrs());
2177 }
2178 
2179 // Look for name only in scope, not in enclosing scopes.
2180 Symbol *ScopeHandler::FindInScope(
2181     const Scope &scope, const parser::Name &name) {
2182   return Resolve(name, FindInScope(scope, name.source));
2183 }
2184 Symbol *ScopeHandler::FindInScope(const Scope &scope, const SourceName &name) {
2185   // all variants of names, e.g. "operator(.ne.)" for "operator(/=)"
2186   for (const std::string &n : GetAllNames(context(), name)) {
2187     auto it{scope.find(SourceName{n})};
2188     if (it != scope.end()) {
2189       return &*it->second;
2190     }
2191   }
2192   return nullptr;
2193 }
2194 
2195 // Find a component or type parameter by name in a derived type or its parents.
2196 Symbol *ScopeHandler::FindInTypeOrParents(
2197     const Scope &scope, const parser::Name &name) {
2198   return Resolve(name, scope.FindComponent(name.source));
2199 }
2200 Symbol *ScopeHandler::FindInTypeOrParents(const parser::Name &name) {
2201   return FindInTypeOrParents(currScope(), name);
2202 }
2203 
2204 void ScopeHandler::EraseSymbol(const parser::Name &name) {
2205   currScope().erase(name.source);
2206   name.symbol = nullptr;
2207 }
2208 
2209 static bool NeedsType(const Symbol &symbol) {
2210   return !symbol.GetType() &&
2211       std::visit(common::visitors{
2212                      [](const EntityDetails &) { return true; },
2213                      [](const ObjectEntityDetails &) { return true; },
2214                      [](const AssocEntityDetails &) { return true; },
2215                      [&](const ProcEntityDetails &p) {
2216                        return symbol.test(Symbol::Flag::Function) &&
2217                            !symbol.attrs().test(Attr::INTRINSIC) &&
2218                            !p.interface().type() && !p.interface().symbol();
2219                      },
2220                      [](const auto &) { return false; },
2221                  },
2222           symbol.details());
2223 }
2224 
2225 void ScopeHandler::ApplyImplicitRules(
2226     Symbol &symbol, bool allowForwardReference) {
2227   if (context().HasError(symbol) || !NeedsType(symbol)) {
2228     return;
2229   }
2230   if (const DeclTypeSpec * type{GetImplicitType(symbol)}) {
2231     symbol.set(Symbol::Flag::Implicit);
2232     symbol.SetType(*type);
2233     return;
2234   }
2235   if (symbol.has<ProcEntityDetails>() && !symbol.attrs().test(Attr::EXTERNAL)) {
2236     std::optional<Symbol::Flag> functionOrSubroutineFlag;
2237     if (symbol.test(Symbol::Flag::Function)) {
2238       functionOrSubroutineFlag = Symbol::Flag::Function;
2239     } else if (symbol.test(Symbol::Flag::Subroutine)) {
2240       functionOrSubroutineFlag = Symbol::Flag::Subroutine;
2241     }
2242     if (IsIntrinsic(symbol.name(), functionOrSubroutineFlag)) {
2243       // type will be determined in expression semantics
2244       AcquireIntrinsicProcedureFlags(symbol);
2245       return;
2246     }
2247   }
2248   if (allowForwardReference && ImplicitlyTypeForwardRef(symbol)) {
2249     return;
2250   }
2251   if (!context().HasError(symbol)) {
2252     Say(symbol.name(), "No explicit type declared for '%s'"_err_en_US);
2253     context().SetError(symbol);
2254   }
2255 }
2256 
2257 // Extension: Allow forward references to scalar integer dummy arguments
2258 // to appear in specification expressions under IMPLICIT NONE(TYPE) when
2259 // what would otherwise have been their implicit type is default INTEGER.
2260 bool ScopeHandler::ImplicitlyTypeForwardRef(Symbol &symbol) {
2261   if (!inSpecificationPart_ || context().HasError(symbol) || !IsDummy(symbol) ||
2262       symbol.Rank() != 0 ||
2263       !context().languageFeatures().IsEnabled(
2264           common::LanguageFeature::ForwardRefDummyImplicitNone)) {
2265     return false;
2266   }
2267   const DeclTypeSpec *type{
2268       GetImplicitType(symbol, false /*ignore IMPLICIT NONE*/)};
2269   if (!type || !type->IsNumeric(TypeCategory::Integer)) {
2270     return false;
2271   }
2272   auto kind{evaluate::ToInt64(type->numericTypeSpec().kind())};
2273   if (!kind || *kind != context().GetDefaultKind(TypeCategory::Integer)) {
2274     return false;
2275   }
2276   if (!ConvertToObjectEntity(symbol)) {
2277     return false;
2278   }
2279   // TODO: check no INTENT(OUT)?
2280   if (context().languageFeatures().ShouldWarn(
2281           common::LanguageFeature::ForwardRefDummyImplicitNone)) {
2282     Say(symbol.name(),
2283         "Dummy argument '%s' was used without being explicitly typed"_warn_en_US,
2284         symbol.name());
2285   }
2286   symbol.set(Symbol::Flag::Implicit);
2287   symbol.SetType(*type);
2288   return true;
2289 }
2290 
2291 // Ensure that the symbol for an intrinsic procedure is marked with
2292 // the INTRINSIC attribute.  Also set PURE &/or ELEMENTAL as
2293 // appropriate.
2294 void ScopeHandler::AcquireIntrinsicProcedureFlags(Symbol &symbol) {
2295   symbol.attrs().set(Attr::INTRINSIC);
2296   switch (context().intrinsics().GetIntrinsicClass(symbol.name().ToString())) {
2297   case evaluate::IntrinsicClass::elementalFunction:
2298   case evaluate::IntrinsicClass::elementalSubroutine:
2299     symbol.attrs().set(Attr::ELEMENTAL);
2300     symbol.attrs().set(Attr::PURE);
2301     break;
2302   case evaluate::IntrinsicClass::impureSubroutine:
2303     break;
2304   default:
2305     symbol.attrs().set(Attr::PURE);
2306   }
2307 }
2308 
2309 const DeclTypeSpec *ScopeHandler::GetImplicitType(
2310     Symbol &symbol, bool respectImplicitNoneType) {
2311   const Scope *scope{&symbol.owner()};
2312   if (scope->IsGlobal()) {
2313     scope = &currScope();
2314   }
2315   scope = &GetInclusiveScope(*scope);
2316   const auto *type{implicitRulesMap_->at(scope).GetType(
2317       symbol.name(), respectImplicitNoneType)};
2318   if (type) {
2319     if (const DerivedTypeSpec * derived{type->AsDerived()}) {
2320       // Resolve any forward-referenced derived type; a quick no-op else.
2321       auto &instantiatable{*const_cast<DerivedTypeSpec *>(derived)};
2322       instantiatable.Instantiate(currScope());
2323     }
2324   }
2325   return type;
2326 }
2327 
2328 // Convert symbol to be a ObjectEntity or return false if it can't be.
2329 bool ScopeHandler::ConvertToObjectEntity(Symbol &symbol) {
2330   if (symbol.has<ObjectEntityDetails>()) {
2331     // nothing to do
2332   } else if (symbol.has<UnknownDetails>()) {
2333     symbol.set_details(ObjectEntityDetails{});
2334   } else if (auto *details{symbol.detailsIf<EntityDetails>()}) {
2335     symbol.set_details(ObjectEntityDetails{std::move(*details)});
2336   } else if (auto *useDetails{symbol.detailsIf<UseDetails>()}) {
2337     return useDetails->symbol().has<ObjectEntityDetails>();
2338   } else {
2339     return false;
2340   }
2341   return true;
2342 }
2343 // Convert symbol to be a ProcEntity or return false if it can't be.
2344 bool ScopeHandler::ConvertToProcEntity(Symbol &symbol) {
2345   if (symbol.has<ProcEntityDetails>()) {
2346     // nothing to do
2347   } else if (symbol.has<UnknownDetails>()) {
2348     symbol.set_details(ProcEntityDetails{});
2349   } else if (auto *details{symbol.detailsIf<EntityDetails>()}) {
2350     symbol.set_details(ProcEntityDetails{std::move(*details)});
2351     if (symbol.GetType() && !symbol.test(Symbol::Flag::Implicit)) {
2352       CHECK(!symbol.test(Symbol::Flag::Subroutine));
2353       symbol.set(Symbol::Flag::Function);
2354     }
2355   } else {
2356     return false;
2357   }
2358   return true;
2359 }
2360 
2361 const DeclTypeSpec &ScopeHandler::MakeNumericType(
2362     TypeCategory category, const std::optional<parser::KindSelector> &kind) {
2363   KindExpr value{GetKindParamExpr(category, kind)};
2364   if (auto known{evaluate::ToInt64(value)}) {
2365     return context().MakeNumericType(category, static_cast<int>(*known));
2366   } else {
2367     return currScope_->MakeNumericType(category, std::move(value));
2368   }
2369 }
2370 
2371 const DeclTypeSpec &ScopeHandler::MakeLogicalType(
2372     const std::optional<parser::KindSelector> &kind) {
2373   KindExpr value{GetKindParamExpr(TypeCategory::Logical, kind)};
2374   if (auto known{evaluate::ToInt64(value)}) {
2375     return context().MakeLogicalType(static_cast<int>(*known));
2376   } else {
2377     return currScope_->MakeLogicalType(std::move(value));
2378   }
2379 }
2380 
2381 void ScopeHandler::NotePossibleBadForwardRef(const parser::Name &name) {
2382   if (inSpecificationPart_ && name.symbol) {
2383     auto kind{currScope().kind()};
2384     if ((kind == Scope::Kind::Subprogram && !currScope().IsStmtFunction()) ||
2385         kind == Scope::Kind::Block) {
2386       bool isHostAssociated{&name.symbol->owner() == &currScope()
2387               ? name.symbol->has<HostAssocDetails>()
2388               : name.symbol->owner().Contains(currScope())};
2389       if (isHostAssociated) {
2390         specPartState_.forwardRefs.insert(name.source);
2391       }
2392     }
2393   }
2394 }
2395 
2396 std::optional<SourceName> ScopeHandler::HadForwardRef(
2397     const Symbol &symbol) const {
2398   auto iter{specPartState_.forwardRefs.find(symbol.name())};
2399   if (iter != specPartState_.forwardRefs.end()) {
2400     return *iter;
2401   }
2402   return std::nullopt;
2403 }
2404 
2405 bool ScopeHandler::CheckPossibleBadForwardRef(const Symbol &symbol) {
2406   if (!context().HasError(symbol)) {
2407     if (auto fwdRef{HadForwardRef(symbol)}) {
2408       const Symbol *outer{symbol.owner().FindSymbol(symbol.name())};
2409       if (outer && symbol.has<UseDetails>() &&
2410           &symbol.GetUltimate() == &outer->GetUltimate()) {
2411         // e.g. IMPORT of host's USE association
2412         return false;
2413       }
2414       Say(*fwdRef,
2415           "Forward reference to '%s' is not allowed in the same specification part"_err_en_US,
2416           *fwdRef)
2417           .Attach(symbol.name(), "Later declaration of '%s'"_en_US, *fwdRef);
2418       context().SetError(symbol);
2419       return true;
2420     }
2421     if (IsDummy(symbol) && isImplicitNoneType() &&
2422         symbol.test(Symbol::Flag::Implicit) && !context().HasError(symbol)) {
2423       // Dummy was implicitly typed despite IMPLICIT NONE(TYPE) in
2424       // ApplyImplicitRules() due to use in a specification expression,
2425       // and no explicit type declaration appeared later.
2426       Say(symbol.name(),
2427           "No explicit type declared for dummy argument '%s'"_err_en_US);
2428       context().SetError(symbol);
2429       return true;
2430     }
2431   }
2432   return false;
2433 }
2434 
2435 void ScopeHandler::MakeExternal(Symbol &symbol) {
2436   if (!symbol.attrs().test(Attr::EXTERNAL)) {
2437     symbol.attrs().set(Attr::EXTERNAL);
2438     if (symbol.attrs().test(Attr::INTRINSIC)) { // C840
2439       Say(symbol.name(),
2440           "Symbol '%s' cannot have both EXTERNAL and INTRINSIC attributes"_err_en_US,
2441           symbol.name());
2442     }
2443   }
2444 }
2445 
2446 // ModuleVisitor implementation
2447 
2448 bool ModuleVisitor::Pre(const parser::Only &x) {
2449   std::visit(common::visitors{
2450                  [&](const Indirection<parser::GenericSpec> &generic) {
2451                    GenericSpecInfo genericSpecInfo{generic.value()};
2452                    AddUseOnly(genericSpecInfo.symbolName());
2453                    AddUse(genericSpecInfo);
2454                  },
2455                  [&](const parser::Name &name) {
2456                    AddUseOnly(name.source);
2457                    Resolve(name, AddUse(name.source, name.source).use);
2458                  },
2459                  [&](const parser::Rename &rename) { Walk(rename); },
2460              },
2461       x.u);
2462   return false;
2463 }
2464 
2465 bool ModuleVisitor::Pre(const parser::Rename::Names &x) {
2466   const auto &localName{std::get<0>(x.t)};
2467   const auto &useName{std::get<1>(x.t)};
2468   AddUseRename(useName.source);
2469   SymbolRename rename{AddUse(localName.source, useName.source)};
2470   if (rename.use) {
2471     EraseRenamedSymbol(*rename.use);
2472   }
2473   Resolve(useName, rename.use);
2474   Resolve(localName, rename.local);
2475   return false;
2476 }
2477 bool ModuleVisitor::Pre(const parser::Rename::Operators &x) {
2478   const parser::DefinedOpName &local{std::get<0>(x.t)};
2479   const parser::DefinedOpName &use{std::get<1>(x.t)};
2480   GenericSpecInfo localInfo{local};
2481   GenericSpecInfo useInfo{use};
2482   if (IsIntrinsicOperator(context(), local.v.source)) {
2483     Say(local.v,
2484         "Intrinsic operator '%s' may not be used as a defined operator"_err_en_US);
2485   } else if (IsLogicalConstant(context(), local.v.source)) {
2486     Say(local.v,
2487         "Logical constant '%s' may not be used as a defined operator"_err_en_US);
2488   } else {
2489     SymbolRename rename{AddUse(localInfo.symbolName(), useInfo.symbolName())};
2490     if (rename.use) {
2491       EraseRenamedSymbol(*rename.use);
2492     }
2493     useInfo.Resolve(rename.use);
2494     localInfo.Resolve(rename.local);
2495   }
2496   return false;
2497 }
2498 
2499 // Set useModuleScope_ to the Scope of the module being used.
2500 bool ModuleVisitor::Pre(const parser::UseStmt &x) {
2501   std::optional<bool> isIntrinsic;
2502   if (x.nature) {
2503     isIntrinsic = *x.nature == parser::UseStmt::ModuleNature::Intrinsic;
2504     AddAndCheckExplicitIntrinsicUse(x.moduleName.source, *isIntrinsic);
2505   } else if (currScope().IsModule() && currScope().symbol() &&
2506       currScope().symbol()->attrs().test(Attr::INTRINSIC)) {
2507     // Intrinsic modules USE only other intrinsic modules
2508     isIntrinsic = true;
2509   }
2510   useModuleScope_ = FindModule(x.moduleName, isIntrinsic);
2511   if (!useModuleScope_) {
2512     return false;
2513   }
2514   // use the name from this source file
2515   useModuleScope_->symbol()->ReplaceName(x.moduleName.source);
2516   return true;
2517 }
2518 
2519 void ModuleVisitor::Post(const parser::UseStmt &x) {
2520   if (const auto *list{std::get_if<std::list<parser::Rename>>(&x.u)}) {
2521     // Not a use-only: collect the names that were used in renames,
2522     // then add a use for each public name that was not renamed.
2523     std::set<SourceName> useNames;
2524     for (const auto &rename : *list) {
2525       std::visit(common::visitors{
2526                      [&](const parser::Rename::Names &names) {
2527                        useNames.insert(std::get<1>(names.t).source);
2528                      },
2529                      [&](const parser::Rename::Operators &ops) {
2530                        useNames.insert(std::get<1>(ops.t).v.source);
2531                      },
2532                  },
2533           rename.u);
2534     }
2535     for (const auto &[name, symbol] : *useModuleScope_) {
2536       if (symbol->attrs().test(Attr::PUBLIC) && !IsUseRenamed(symbol->name()) &&
2537           (!symbol->attrs().test(Attr::INTRINSIC) ||
2538               symbol->has<UseDetails>()) &&
2539           !symbol->has<MiscDetails>() && useNames.count(name) == 0) {
2540         SourceName location{x.moduleName.source};
2541         if (auto *localSymbol{FindInScope(name)}) {
2542           DoAddUse(location, localSymbol->name(), *localSymbol, *symbol);
2543         } else {
2544           DoAddUse(location, location, CopySymbol(name, *symbol), *symbol);
2545         }
2546       }
2547     }
2548   }
2549   useModuleScope_ = nullptr;
2550 }
2551 
2552 ModuleVisitor::SymbolRename ModuleVisitor::AddUse(
2553     const SourceName &localName, const SourceName &useName) {
2554   return AddUse(localName, useName, FindInScope(*useModuleScope_, useName));
2555 }
2556 
2557 ModuleVisitor::SymbolRename ModuleVisitor::AddUse(
2558     const SourceName &localName, const SourceName &useName, Symbol *useSymbol) {
2559   if (!useModuleScope_) {
2560     return {}; // error occurred finding module
2561   }
2562   if (!useSymbol) {
2563     Say(useName, "'%s' not found in module '%s'"_err_en_US, MakeOpName(useName),
2564         useModuleScope_->GetName().value());
2565     return {};
2566   }
2567   if (useSymbol->attrs().test(Attr::PRIVATE) &&
2568       !FindModuleFileContaining(currScope())) {
2569     // Privacy is not enforced in module files so that generic interfaces
2570     // can be resolved to private specific procedures in specification
2571     // expressions.
2572     Say(useName, "'%s' is PRIVATE in '%s'"_err_en_US, MakeOpName(useName),
2573         useModuleScope_->GetName().value());
2574     return {};
2575   }
2576   auto &localSymbol{MakeSymbol(localName)};
2577   DoAddUse(useName, localName, localSymbol, *useSymbol);
2578   return {&localSymbol, useSymbol};
2579 }
2580 
2581 // symbol must be either a Use or a Generic formed by merging two uses.
2582 // Convert it to a UseError with this additional location.
2583 static void ConvertToUseError(
2584     Symbol &symbol, const SourceName &location, const Scope &module) {
2585   const auto *useDetails{symbol.detailsIf<UseDetails>()};
2586   if (!useDetails) {
2587     auto &genericDetails{symbol.get<GenericDetails>()};
2588     useDetails = &genericDetails.uses().at(0)->get<UseDetails>();
2589   }
2590   symbol.set_details(
2591       UseErrorDetails{*useDetails}.add_occurrence(location, module));
2592 }
2593 
2594 // If a symbol has previously been USE-associated and did not appear in a USE
2595 // ONLY clause, erase it from the current scope.  This is needed when a name
2596 // appears in a USE rename clause.
2597 void ModuleVisitor::EraseRenamedSymbol(const Symbol &useSymbol) {
2598   const SourceName &name{useSymbol.name()};
2599   if (const Symbol * symbol{FindInScope(name)}) {
2600     if (auto *useDetails{symbol->detailsIf<UseDetails>()}) {
2601       const Symbol &moduleSymbol{useDetails->symbol()};
2602       if (moduleSymbol.name() == name &&
2603           moduleSymbol.owner() == useSymbol.owner() && IsUseRenamed(name) &&
2604           !IsUseOnly(name)) {
2605         EraseSymbol(*symbol);
2606       }
2607     }
2608   }
2609 }
2610 
2611 void ModuleVisitor::DoAddUse(const SourceName &location,
2612     const SourceName &localName, Symbol &localSymbol, const Symbol &useSymbol) {
2613   if (localName != useSymbol.name()) {
2614     EraseRenamedSymbol(useSymbol);
2615   }
2616   localSymbol.attrs() = useSymbol.attrs() & ~Attrs{Attr::PUBLIC, Attr::PRIVATE};
2617   localSymbol.flags() = useSymbol.flags();
2618   const Symbol &useUltimate{useSymbol.GetUltimate()};
2619   if (auto *useDetails{localSymbol.detailsIf<UseDetails>()}) {
2620     const Symbol &localUltimate{localSymbol.GetUltimate()};
2621     if (localUltimate.owner() == useUltimate.owner()) {
2622       // use-associating the same symbol again -- ok
2623     } else if (localUltimate.has<GenericDetails>() &&
2624         useUltimate.has<GenericDetails>()) {
2625       // use-associating generics with the same names: merge them into a
2626       // new generic in this scope
2627       auto generic1{localUltimate.get<GenericDetails>()};
2628       AddGenericUse(generic1, localName, useUltimate);
2629       generic1.AddUse(localSymbol);
2630       // useSymbol has specific g and so does generic1
2631       auto &generic2{useUltimate.get<GenericDetails>()};
2632       if (generic1.derivedType() && generic2.derivedType() &&
2633           generic1.derivedType() != generic2.derivedType()) {
2634         Say(location,
2635             "Generic interface '%s' has ambiguous derived types"
2636             " from modules '%s' and '%s'"_err_en_US,
2637             localSymbol.name(), GetUsedModule(*useDetails).name(),
2638             useUltimate.owner().GetName().value());
2639         context().SetError(localSymbol);
2640       } else {
2641         generic1.CopyFrom(generic2);
2642       }
2643       EraseSymbol(localSymbol);
2644       MakeSymbol(localSymbol.name(), localSymbol.attrs(), std::move(generic1));
2645     } else {
2646       ConvertToUseError(localSymbol, location, *useModuleScope_);
2647     }
2648   } else if (auto *genericDetails{localSymbol.detailsIf<GenericDetails>()}) {
2649     if (const auto *useDetails{useUltimate.detailsIf<GenericDetails>()}) {
2650       AddGenericUse(*genericDetails, localName, useUltimate);
2651       if (genericDetails->derivedType() && useDetails->derivedType() &&
2652           genericDetails->derivedType() != useDetails->derivedType()) {
2653         Say(location,
2654             "Generic interface '%s' has ambiguous derived types"
2655             " from modules '%s' and '%s'"_err_en_US,
2656             localSymbol.name(),
2657             genericDetails->derivedType()->owner().GetName().value(),
2658             useDetails->derivedType()->owner().GetName().value());
2659       } else {
2660         genericDetails->CopyFrom(*useDetails);
2661       }
2662     } else {
2663       ConvertToUseError(localSymbol, location, *useModuleScope_);
2664     }
2665   } else if (auto *details{localSymbol.detailsIf<UseErrorDetails>()}) {
2666     details->add_occurrence(location, *useModuleScope_);
2667   } else if (!localSymbol.has<UnknownDetails>()) {
2668     Say(location,
2669         "Cannot use-associate '%s'; it is already declared in this scope"_err_en_US,
2670         localName)
2671         .Attach(localSymbol.name(), "Previous declaration of '%s'"_en_US,
2672             localName);
2673   } else {
2674     localSymbol.set_details(UseDetails{localName, useSymbol});
2675   }
2676 }
2677 
2678 void ModuleVisitor::AddUse(const GenericSpecInfo &info) {
2679   if (useModuleScope_) {
2680     const auto &name{info.symbolName()};
2681     auto rename{AddUse(name, name, FindInScope(*useModuleScope_, name))};
2682     info.Resolve(rename.use);
2683   }
2684 }
2685 
2686 // Create a UseDetails symbol for this USE and add it to generic
2687 void ModuleVisitor::AddGenericUse(
2688     GenericDetails &generic, const SourceName &name, const Symbol &useSymbol) {
2689   generic.AddUse(currScope().MakeSymbol(name, {}, UseDetails{name, useSymbol}));
2690 }
2691 
2692 // Enforce C1406
2693 void ModuleVisitor::AddAndCheckExplicitIntrinsicUse(
2694     SourceName name, bool isIntrinsic) {
2695   if (isIntrinsic) {
2696     if (auto iter{explicitNonIntrinsicUses_.find(name)};
2697         iter != explicitNonIntrinsicUses_.end()) {
2698       Say(name,
2699           "Cannot USE,INTRINSIC module '%s' in the same scope as USE,NON_INTRINSIC"_err_en_US,
2700           name)
2701           .Attach(*iter, "Previous USE of '%s'"_en_US, *iter);
2702     }
2703     explicitIntrinsicUses_.insert(name);
2704   } else {
2705     if (auto iter{explicitIntrinsicUses_.find(name)};
2706         iter != explicitIntrinsicUses_.end()) {
2707       Say(name,
2708           "Cannot USE,NON_INTRINSIC module '%s' in the same scope as USE,INTRINSIC"_err_en_US,
2709           name)
2710           .Attach(*iter, "Previous USE of '%s'"_en_US, *iter);
2711     }
2712     explicitNonIntrinsicUses_.insert(name);
2713   }
2714 }
2715 
2716 bool ModuleVisitor::BeginSubmodule(
2717     const parser::Name &name, const parser::ParentIdentifier &parentId) {
2718   auto &ancestorName{std::get<parser::Name>(parentId.t)};
2719   auto &parentName{std::get<std::optional<parser::Name>>(parentId.t)};
2720   Scope *ancestor{FindModule(ancestorName, false /*not intrinsic*/)};
2721   if (!ancestor) {
2722     return false;
2723   }
2724   Scope *parentScope{parentName
2725           ? FindModule(*parentName, false /*not intrinsic*/, ancestor)
2726           : ancestor};
2727   if (!parentScope) {
2728     return false;
2729   }
2730   PushScope(*parentScope); // submodule is hosted in parent
2731   BeginModule(name, true);
2732   if (!ancestor->AddSubmodule(name.source, currScope())) {
2733     Say(name, "Module '%s' already has a submodule named '%s'"_err_en_US,
2734         ancestorName.source, name.source);
2735   }
2736   return true;
2737 }
2738 
2739 void ModuleVisitor::BeginModule(const parser::Name &name, bool isSubmodule) {
2740   auto &symbol{MakeSymbol(name, ModuleDetails{isSubmodule})};
2741   auto &details{symbol.get<ModuleDetails>()};
2742   PushScope(Scope::Kind::Module, &symbol);
2743   details.set_scope(&currScope());
2744   defaultAccess_ = Attr::PUBLIC;
2745   prevAccessStmt_ = std::nullopt;
2746 }
2747 
2748 // Find a module or submodule by name and return its scope.
2749 // If ancestor is present, look for a submodule of that ancestor module.
2750 // May have to read a .mod file to find it.
2751 // If an error occurs, report it and return nullptr.
2752 Scope *ModuleVisitor::FindModule(const parser::Name &name,
2753     std::optional<bool> isIntrinsic, Scope *ancestor) {
2754   ModFileReader reader{context()};
2755   Scope *scope{reader.Read(name.source, isIntrinsic, ancestor)};
2756   if (!scope) {
2757     return nullptr;
2758   }
2759   if (scope->kind() != Scope::Kind::Module) {
2760     Say(name, "'%s' is not a module"_err_en_US);
2761     return nullptr;
2762   }
2763   if (DoesScopeContain(scope, currScope())) { // 14.2.2(1)
2764     Say(name, "Module '%s' cannot USE itself"_err_en_US);
2765   }
2766   Resolve(name, scope->symbol());
2767   return scope;
2768 }
2769 
2770 void ModuleVisitor::ApplyDefaultAccess() {
2771   for (auto &pair : currScope()) {
2772     Symbol &symbol = *pair.second;
2773     if (!symbol.attrs().HasAny({Attr::PUBLIC, Attr::PRIVATE})) {
2774       symbol.attrs().set(defaultAccess_);
2775     }
2776   }
2777 }
2778 
2779 // InterfaceVistor implementation
2780 
2781 bool InterfaceVisitor::Pre(const parser::InterfaceStmt &x) {
2782   bool isAbstract{std::holds_alternative<parser::Abstract>(x.u)};
2783   genericInfo_.emplace(/*isInterface*/ true, isAbstract);
2784   return BeginAttrs();
2785 }
2786 
2787 void InterfaceVisitor::Post(const parser::InterfaceStmt &) { EndAttrs(); }
2788 
2789 void InterfaceVisitor::Post(const parser::EndInterfaceStmt &) {
2790   genericInfo_.pop();
2791 }
2792 
2793 // Create a symbol in genericSymbol_ for this GenericSpec.
2794 bool InterfaceVisitor::Pre(const parser::GenericSpec &x) {
2795   if (auto *symbol{FindInScope(GenericSpecInfo{x}.symbolName())}) {
2796     SetGenericSymbol(*symbol);
2797   }
2798   return false;
2799 }
2800 
2801 bool InterfaceVisitor::Pre(const parser::ProcedureStmt &x) {
2802   if (!isGeneric()) {
2803     Say("A PROCEDURE statement is only allowed in a generic interface block"_err_en_US);
2804     return false;
2805   }
2806   auto kind{std::get<parser::ProcedureStmt::Kind>(x.t)};
2807   const auto &names{std::get<std::list<parser::Name>>(x.t)};
2808   AddSpecificProcs(names, kind);
2809   return false;
2810 }
2811 
2812 bool InterfaceVisitor::Pre(const parser::GenericStmt &) {
2813   genericInfo_.emplace(/*isInterface*/ false);
2814   return true;
2815 }
2816 void InterfaceVisitor::Post(const parser::GenericStmt &x) {
2817   if (auto &accessSpec{std::get<std::optional<parser::AccessSpec>>(x.t)}) {
2818     GetGenericInfo().symbol->attrs().set(AccessSpecToAttr(*accessSpec));
2819   }
2820   const auto &names{std::get<std::list<parser::Name>>(x.t)};
2821   AddSpecificProcs(names, ProcedureKind::Procedure);
2822   genericInfo_.pop();
2823 }
2824 
2825 bool InterfaceVisitor::inInterfaceBlock() const {
2826   return !genericInfo_.empty() && GetGenericInfo().isInterface;
2827 }
2828 bool InterfaceVisitor::isGeneric() const {
2829   return !genericInfo_.empty() && GetGenericInfo().symbol;
2830 }
2831 bool InterfaceVisitor::isAbstract() const {
2832   return !genericInfo_.empty() && GetGenericInfo().isAbstract;
2833 }
2834 
2835 void InterfaceVisitor::AddSpecificProcs(
2836     const std::list<parser::Name> &names, ProcedureKind kind) {
2837   for (const auto &name : names) {
2838     specificProcs_.emplace(
2839         GetGenericInfo().symbol, std::make_pair(&name, kind));
2840   }
2841 }
2842 
2843 // By now we should have seen all specific procedures referenced by name in
2844 // this generic interface. Resolve those names to symbols.
2845 void InterfaceVisitor::ResolveSpecificsInGeneric(Symbol &generic) {
2846   auto &details{generic.get<GenericDetails>()};
2847   UnorderedSymbolSet symbolsSeen;
2848   for (const Symbol &symbol : details.specificProcs()) {
2849     symbolsSeen.insert(symbol.GetUltimate());
2850   }
2851   auto range{specificProcs_.equal_range(&generic)};
2852   for (auto it{range.first}; it != range.second; ++it) {
2853     const parser::Name *name{it->second.first};
2854     auto kind{it->second.second};
2855     const auto *symbol{FindSymbol(*name)};
2856     if (!symbol) {
2857       Say(*name, "Procedure '%s' not found"_err_en_US);
2858       continue;
2859     }
2860     const Symbol &specific{BypassGeneric(*symbol)};
2861     const Symbol &ultimate{specific.GetUltimate()};
2862     if (!ultimate.has<SubprogramDetails>() &&
2863         !ultimate.has<SubprogramNameDetails>()) {
2864       Say(*name, "'%s' is not a subprogram"_err_en_US);
2865       continue;
2866     }
2867     if (kind == ProcedureKind::ModuleProcedure) {
2868       if (const auto *nd{ultimate.detailsIf<SubprogramNameDetails>()}) {
2869         if (nd->kind() != SubprogramKind::Module) {
2870           Say(*name, "'%s' is not a module procedure"_err_en_US);
2871         }
2872       } else {
2873         // USE-associated procedure
2874         const auto *sd{ultimate.detailsIf<SubprogramDetails>()};
2875         CHECK(sd);
2876         if (ultimate.owner().kind() != Scope::Kind::Module ||
2877             sd->isInterface()) {
2878           Say(*name, "'%s' is not a module procedure"_err_en_US);
2879         }
2880       }
2881     }
2882     if (symbolsSeen.insert(ultimate).second /*true if added*/) {
2883       // When a specific procedure is a USE association, that association
2884       // is saved in the generic's specifics, not its ultimate symbol,
2885       // so that module file output of interfaces can distinguish them.
2886       details.AddSpecificProc(specific, name->source);
2887     } else if (&specific == &ultimate) {
2888       Say(name->source,
2889           "Procedure '%s' is already specified in generic '%s'"_err_en_US,
2890           name->source, MakeOpName(generic.name()));
2891     } else {
2892       Say(name->source,
2893           "Procedure '%s' from module '%s' is already specified in generic '%s'"_err_en_US,
2894           ultimate.name(), ultimate.owner().GetName().value(),
2895           MakeOpName(generic.name()));
2896     }
2897   }
2898   specificProcs_.erase(range.first, range.second);
2899 }
2900 
2901 // Check that the specific procedures are all functions or all subroutines.
2902 // If there is a derived type with the same name they must be functions.
2903 // Set the corresponding flag on generic.
2904 void InterfaceVisitor::CheckGenericProcedures(Symbol &generic) {
2905   ResolveSpecificsInGeneric(generic);
2906   auto &details{generic.get<GenericDetails>()};
2907   if (auto *proc{details.CheckSpecific()}) {
2908     auto msg{
2909         "'%s' may not be the name of both a generic interface and a"
2910         " procedure unless it is a specific procedure of the generic"_err_en_US};
2911     if (proc->name().begin() > generic.name().begin()) {
2912       Say(proc->name(), std::move(msg));
2913     } else {
2914       Say(generic.name(), std::move(msg));
2915     }
2916   }
2917   auto &specifics{details.specificProcs()};
2918   if (specifics.empty()) {
2919     if (details.derivedType()) {
2920       generic.set(Symbol::Flag::Function);
2921     }
2922     return;
2923   }
2924   const Symbol &firstSpecific{specifics.front()};
2925   bool isFunction{firstSpecific.test(Symbol::Flag::Function)};
2926   for (const Symbol &specific : specifics) {
2927     if (isFunction != specific.test(Symbol::Flag::Function)) { // C1514
2928       auto &msg{Say(generic.name(),
2929           "Generic interface '%s' has both a function and a subroutine"_err_en_US)};
2930       if (isFunction) {
2931         msg.Attach(firstSpecific.name(), "Function declaration"_en_US);
2932         msg.Attach(specific.name(), "Subroutine declaration"_en_US);
2933       } else {
2934         msg.Attach(firstSpecific.name(), "Subroutine declaration"_en_US);
2935         msg.Attach(specific.name(), "Function declaration"_en_US);
2936       }
2937     }
2938   }
2939   if (!isFunction && details.derivedType()) {
2940     SayDerivedType(generic.name(),
2941         "Generic interface '%s' may only contain functions due to derived type"
2942         " with same name"_err_en_US,
2943         *details.derivedType()->scope());
2944   }
2945   generic.set(isFunction ? Symbol::Flag::Function : Symbol::Flag::Subroutine);
2946 }
2947 
2948 // SubprogramVisitor implementation
2949 
2950 SubprogramVisitor::~SubprogramVisitor() { CHECK(funcInfoStack_.empty()); }
2951 
2952 // Return false if it is actually an assignment statement.
2953 bool SubprogramVisitor::HandleStmtFunction(const parser::StmtFunctionStmt &x) {
2954   const auto &name{std::get<parser::Name>(x.t)};
2955   const DeclTypeSpec *resultType{nullptr};
2956   // Look up name: provides return type or tells us if it's an array
2957   if (auto *symbol{FindSymbol(name)}) {
2958     auto *details{symbol->detailsIf<EntityDetails>()};
2959     if (!details) {
2960       badStmtFuncFound_ = true;
2961       return false;
2962     }
2963     // TODO: check that attrs are compatible with stmt func
2964     resultType = details->type();
2965     symbol->details() = UnknownDetails{}; // will be replaced below
2966   }
2967   if (badStmtFuncFound_) {
2968     Say(name, "'%s' has not been declared as an array"_err_en_US);
2969     return true;
2970   }
2971   auto &symbol{PushSubprogramScope(name, Symbol::Flag::Function)};
2972   symbol.set(Symbol::Flag::StmtFunction);
2973   EraseSymbol(symbol); // removes symbol added by PushSubprogramScope
2974   auto &details{symbol.get<SubprogramDetails>()};
2975   for (const auto &dummyName : std::get<std::list<parser::Name>>(x.t)) {
2976     ObjectEntityDetails dummyDetails{true};
2977     if (auto *dummySymbol{FindInScope(currScope().parent(), dummyName)}) {
2978       if (auto *d{dummySymbol->detailsIf<EntityDetails>()}) {
2979         if (d->type()) {
2980           dummyDetails.set_type(*d->type());
2981         }
2982       }
2983     }
2984     Symbol &dummy{MakeSymbol(dummyName, std::move(dummyDetails))};
2985     ApplyImplicitRules(dummy);
2986     details.add_dummyArg(dummy);
2987   }
2988   ObjectEntityDetails resultDetails;
2989   if (resultType) {
2990     resultDetails.set_type(*resultType);
2991   }
2992   resultDetails.set_funcResult(true);
2993   Symbol &result{MakeSymbol(name, std::move(resultDetails))};
2994   ApplyImplicitRules(result);
2995   details.set_result(result);
2996   const auto &parsedExpr{std::get<parser::Scalar<parser::Expr>>(x.t)};
2997   Walk(parsedExpr);
2998   // The analysis of the expression that constitutes the body of the
2999   // statement function is deferred to FinishSpecificationPart() so that
3000   // all declarations and implicit typing are complete.
3001   PopScope();
3002   return true;
3003 }
3004 
3005 bool SubprogramVisitor::Pre(const parser::Suffix &suffix) {
3006   if (suffix.resultName) {
3007     if (IsFunction(currScope())) {
3008       if (!funcInfoStack_.empty()) {
3009         FuncInfo &info{funcInfoStack_.back()};
3010         if (info.inFunctionStmt) {
3011           info.resultName = &suffix.resultName.value();
3012         } else {
3013           // will check the result name in Post(EntryStmt)
3014         }
3015       }
3016     } else {
3017       Message &msg{Say(*suffix.resultName,
3018           "RESULT(%s) may appear only in a function"_err_en_US)};
3019       if (const Symbol * subprogram{InclusiveScope().symbol()}) {
3020         msg.Attach(subprogram->name(), "Containing subprogram"_en_US);
3021       }
3022     }
3023   }
3024   return true;
3025 }
3026 
3027 bool SubprogramVisitor::Pre(const parser::PrefixSpec &x) {
3028   // Save this to process after UseStmt and ImplicitPart
3029   if (const auto *parsedType{std::get_if<parser::DeclarationTypeSpec>(&x.u)}) {
3030     CHECK(!funcInfoStack_.empty());
3031     FuncInfo &info{funcInfoStack_.back()};
3032     if (info.parsedType) { // C1543
3033       Say(currStmtSource().value(),
3034           "FUNCTION prefix cannot specify the type more than once"_err_en_US);
3035       return false;
3036     } else {
3037       info.parsedType = parsedType;
3038       info.source = currStmtSource();
3039       return false;
3040     }
3041   } else {
3042     return true;
3043   }
3044 }
3045 
3046 void SubprogramVisitor::FinishFunctionResult() {
3047   // If the function has a type in the prefix, process it now.
3048   if (IsFunction(currScope())) {
3049     CHECK(!funcInfoStack_.empty());
3050     FuncInfo &info{funcInfoStack_.back()};
3051     if (info.parsedType) {
3052       messageHandler().set_currStmtSource(info.source);
3053       if (const auto *type{ProcessTypeSpec(*info.parsedType, true)}) {
3054         if (!context().HasError(info.resultSymbol)) {
3055           info.resultSymbol->SetType(*type);
3056         }
3057       }
3058       info.parsedType = nullptr;
3059     }
3060   }
3061 }
3062 
3063 bool SubprogramVisitor::Pre(const parser::InterfaceBody::Subroutine &x) {
3064   const auto &name{std::get<parser::Name>(
3065       std::get<parser::Statement<parser::SubroutineStmt>>(x.t).statement.t)};
3066   return BeginSubprogram(name, Symbol::Flag::Subroutine);
3067 }
3068 void SubprogramVisitor::Post(const parser::InterfaceBody::Subroutine &) {
3069   EndSubprogram();
3070 }
3071 bool SubprogramVisitor::Pre(const parser::InterfaceBody::Function &x) {
3072   const auto &name{std::get<parser::Name>(
3073       std::get<parser::Statement<parser::FunctionStmt>>(x.t).statement.t)};
3074   return BeginSubprogram(name, Symbol::Flag::Function);
3075 }
3076 void SubprogramVisitor::Post(const parser::InterfaceBody::Function &) {
3077   EndSubprogram();
3078 }
3079 
3080 bool SubprogramVisitor::Pre(const parser::SubroutineStmt &) {
3081   return BeginAttrs();
3082 }
3083 bool SubprogramVisitor::Pre(const parser::FunctionStmt &) {
3084   CHECK(!funcInfoStack_.empty());
3085   FuncInfo &info{funcInfoStack_.back()};
3086   CHECK(!info.inFunctionStmt);
3087   info.inFunctionStmt = true;
3088   return BeginAttrs();
3089 }
3090 bool SubprogramVisitor::Pre(const parser::EntryStmt &) { return BeginAttrs(); }
3091 
3092 void SubprogramVisitor::Post(const parser::SubroutineStmt &stmt) {
3093   const auto &name{std::get<parser::Name>(stmt.t)};
3094   auto &details{PostSubprogramStmt(name)};
3095   for (const auto &dummyArg : std::get<std::list<parser::DummyArg>>(stmt.t)) {
3096     if (const auto *dummyName{std::get_if<parser::Name>(&dummyArg.u)}) {
3097       Symbol &dummy{MakeSymbol(*dummyName, EntityDetails{true})};
3098       details.add_dummyArg(dummy);
3099     } else {
3100       details.add_alternateReturn();
3101     }
3102   }
3103 }
3104 
3105 void SubprogramVisitor::Post(const parser::FunctionStmt &stmt) {
3106   const auto &name{std::get<parser::Name>(stmt.t)};
3107   auto &details{PostSubprogramStmt(name)};
3108   for (const auto &dummyName : std::get<std::list<parser::Name>>(stmt.t)) {
3109     Symbol &dummy{MakeSymbol(dummyName, EntityDetails{true})};
3110     details.add_dummyArg(dummy);
3111   }
3112   const parser::Name *funcResultName;
3113   CHECK(!funcInfoStack_.empty());
3114   FuncInfo &info{funcInfoStack_.back()};
3115   CHECK(info.inFunctionStmt);
3116   info.inFunctionStmt = false;
3117   if (info.resultName && info.resultName->source != name.source) {
3118     // Note that RESULT is ignored if it has the same name as the function.
3119     funcResultName = info.resultName;
3120   } else {
3121     EraseSymbol(name); // was added by PushSubprogramScope
3122     funcResultName = &name;
3123   }
3124   // add function result to function scope
3125   if (details.isFunction()) {
3126     CHECK(context().HasError(currScope().symbol()));
3127   } else {
3128     // add function result to function scope
3129     EntityDetails funcResultDetails;
3130     funcResultDetails.set_funcResult(true);
3131     funcInfoStack_.back().resultSymbol =
3132         &MakeSymbol(*funcResultName, std::move(funcResultDetails));
3133     details.set_result(*funcInfoStack_.back().resultSymbol);
3134   }
3135   // C1560.
3136   if (info.resultName && info.resultName->source == name.source) {
3137     Say(info.resultName->source,
3138         "The function name should not appear in RESULT, references to '%s' "
3139         "inside the function will be considered as references to the "
3140         "result only"_warn_en_US,
3141         name.source);
3142     // RESULT name was ignored above, the only side effect from doing so will be
3143     // the inability to make recursive calls. The related parser::Name is still
3144     // resolved to the created function result symbol because every parser::Name
3145     // should be resolved to avoid internal errors.
3146     Resolve(*info.resultName, info.resultSymbol);
3147   }
3148   name.symbol = currScope().symbol(); // must not be function result symbol
3149   // Clear the RESULT() name now in case an ENTRY statement in the implicit-part
3150   // has a RESULT() suffix.
3151   info.resultName = nullptr;
3152   // If there was a type on the function statement, and it is an intrinsic
3153   // type, process that type now so that inquiries in specification expressions
3154   // will work.  Derived types are deferred to the end of the specification part
3155   // so that they can resolve to a locally declared type.
3156   if (info.parsedType &&
3157       std::holds_alternative<parser::IntrinsicTypeSpec>(info.parsedType->u)) {
3158     FinishFunctionResult();
3159   }
3160 }
3161 
3162 SubprogramDetails &SubprogramVisitor::PostSubprogramStmt(
3163     const parser::Name &name) {
3164   Symbol &symbol{*currScope().symbol()};
3165   CHECK(name.source == symbol.name());
3166   SetBindNameOn(symbol);
3167   symbol.attrs() |= EndAttrs();
3168   if (symbol.attrs().test(Attr::MODULE)) {
3169     symbol.attrs().set(Attr::EXTERNAL, false);
3170   }
3171   return symbol.get<SubprogramDetails>();
3172 }
3173 
3174 void SubprogramVisitor::Post(const parser::EntryStmt &stmt) {
3175   auto attrs{EndAttrs()}; // needs to be called even if early return
3176   Scope &inclusiveScope{InclusiveScope()};
3177   const Symbol *subprogram{inclusiveScope.symbol()};
3178   if (!subprogram) {
3179     CHECK(context().AnyFatalError());
3180     return;
3181   }
3182   const auto &name{std::get<parser::Name>(stmt.t)};
3183   const parser::Name *resultName{nullptr};
3184   if (const auto &maybeSuffix{
3185           std::get<std::optional<parser::Suffix>>(stmt.t)}) {
3186     resultName = common::GetPtrFromOptional(maybeSuffix->resultName);
3187   }
3188   bool inFunction{IsFunction(currScope())};
3189   if (resultName) { // RESULT(result) is present
3190     if (!inFunction) {
3191       // error was already emitted for the suffix
3192     } else if (resultName->source == subprogram->name()) { // C1574
3193       Say2(resultName->source,
3194           "RESULT(%s) may not have the same name as the function"_err_en_US,
3195           subprogram->name(), "Containing function"_en_US);
3196     } else if (const Symbol *
3197         symbol{FindSymbol(inclusiveScope.parent(), *resultName)}) { // C1574
3198       if (const auto *details{symbol->detailsIf<SubprogramDetails>()}) {
3199         if (details->entryScope() == &inclusiveScope) {
3200           Say2(resultName->source,
3201               "RESULT(%s) may not have the same name as an ENTRY in the function"_err_en_US,
3202               symbol->name(), "Conflicting ENTRY"_en_US);
3203         }
3204       }
3205     }
3206     if (Symbol * symbol{FindSymbol(name)}) { // C1570
3207       // When RESULT() appears, ENTRY name can't have been already declared
3208       if (inclusiveScope.Contains(symbol->owner())) {
3209         Say2(name,
3210             "ENTRY name '%s' may not be declared when RESULT() is present"_err_en_US,
3211             *symbol, "Previous declaration of '%s'"_en_US);
3212       }
3213     }
3214     if (resultName->source == name.source) {
3215       // ignore RESULT() hereafter when it's the same name as the ENTRY
3216       resultName = nullptr;
3217     }
3218   }
3219   SubprogramDetails entryDetails;
3220   entryDetails.set_entryScope(inclusiveScope);
3221   if (inFunction) {
3222     // Create the entity to hold the function result, if necessary.
3223     Symbol *resultSymbol{nullptr};
3224     auto &effectiveResultName{*(resultName ? resultName : &name)};
3225     resultSymbol = FindInScope(currScope(), effectiveResultName);
3226     if (resultSymbol) { // C1574
3227       std::visit(
3228           common::visitors{[](EntityDetails &x) { x.set_funcResult(true); },
3229               [](ObjectEntityDetails &x) { x.set_funcResult(true); },
3230               [](ProcEntityDetails &x) { x.set_funcResult(true); },
3231               [&](const auto &) {
3232                 Say2(effectiveResultName.source,
3233                     "'%s' was previously declared as an item that may not be used as a function result"_err_en_US,
3234                     resultSymbol->name(), "Previous declaration of '%s'"_en_US);
3235                 context().SetError(*resultSymbol);
3236               }},
3237           resultSymbol->details());
3238     } else if (inExecutionPart_) {
3239       ObjectEntityDetails entity;
3240       entity.set_funcResult(true);
3241       resultSymbol = &MakeSymbol(effectiveResultName, std::move(entity));
3242       ApplyImplicitRules(*resultSymbol);
3243     } else {
3244       EntityDetails entity;
3245       entity.set_funcResult(true);
3246       resultSymbol = &MakeSymbol(effectiveResultName, std::move(entity));
3247     }
3248     if (!resultName) {
3249       name.symbol = nullptr; // symbol will be used for entry point below
3250     }
3251     entryDetails.set_result(*resultSymbol);
3252   }
3253 
3254   for (const auto &dummyArg : std::get<std::list<parser::DummyArg>>(stmt.t)) {
3255     if (const auto *dummyName{std::get_if<parser::Name>(&dummyArg.u)}) {
3256       Symbol *dummy{FindSymbol(*dummyName)};
3257       if (dummy) {
3258         std::visit(
3259             common::visitors{[](EntityDetails &x) { x.set_isDummy(); },
3260                 [](ObjectEntityDetails &x) { x.set_isDummy(); },
3261                 [](ProcEntityDetails &x) { x.set_isDummy(); },
3262                 [](SubprogramDetails &x) { x.set_isDummy(); },
3263                 [&](const auto &) {
3264                   Say2(dummyName->source,
3265                       "ENTRY dummy argument '%s' is previously declared as an item that may not be used as a dummy argument"_err_en_US,
3266                       dummy->name(), "Previous declaration of '%s'"_en_US);
3267                 }},
3268             dummy->details());
3269       } else {
3270         dummy = &MakeSymbol(*dummyName, EntityDetails{true});
3271         if (inExecutionPart_) {
3272           ApplyImplicitRules(*dummy);
3273         }
3274       }
3275       entryDetails.add_dummyArg(*dummy);
3276     } else {
3277       if (inFunction) { // C1573
3278         Say(name,
3279             "ENTRY in a function may not have an alternate return dummy argument"_err_en_US);
3280         break;
3281       }
3282       entryDetails.add_alternateReturn();
3283     }
3284   }
3285 
3286   Symbol::Flag subpFlag{
3287       inFunction ? Symbol::Flag::Function : Symbol::Flag::Subroutine};
3288   Scope &outer{inclusiveScope.parent()}; // global or module scope
3289   if (outer.IsModule() && !attrs.test(Attr::PRIVATE)) {
3290     attrs.set(Attr::PUBLIC);
3291   }
3292   if (Symbol * extant{FindSymbol(outer, name)}) {
3293     if (!HandlePreviousCalls(name, *extant, subpFlag)) {
3294       if (outer.IsGlobal()) {
3295         Say2(name, "'%s' is already defined as a global identifier"_err_en_US,
3296             *extant, "Previous definition of '%s'"_en_US);
3297       } else {
3298         SayAlreadyDeclared(name, *extant);
3299       }
3300       return;
3301     }
3302   }
3303   Symbol &entrySymbol{MakeSymbol(outer, name.source, attrs)};
3304   entrySymbol.set_details(std::move(entryDetails));
3305   SetBindNameOn(entrySymbol);
3306   entrySymbol.set(subpFlag);
3307   Resolve(name, entrySymbol);
3308 }
3309 
3310 // A subprogram declared with MODULE PROCEDURE
3311 bool SubprogramVisitor::BeginMpSubprogram(const parser::Name &name) {
3312   auto *symbol{FindSymbol(name)};
3313   if (symbol && symbol->has<SubprogramNameDetails>()) {
3314     symbol = FindSymbol(currScope().parent(), name);
3315   }
3316   if (!IsSeparateModuleProcedureInterface(symbol)) {
3317     Say(name, "'%s' was not declared a separate module procedure"_err_en_US);
3318     return false;
3319   }
3320   if (symbol->owner() == currScope() && symbol->scope()) {
3321     // This is a MODULE PROCEDURE whose interface appears in its host.
3322     // Convert the module procedure's interface into a subprogram.
3323     SetScope(DEREF(symbol->scope()));
3324     symbol->get<SubprogramDetails>().set_isInterface(false);
3325     if (IsFunction(*symbol)) {
3326       funcInfoStack_.emplace_back(); // just to be popped later
3327     }
3328   } else {
3329     // Copy the interface into a new subprogram scope.
3330     Symbol &newSymbol{MakeSymbol(name, SubprogramDetails{})};
3331     PushScope(Scope::Kind::Subprogram, &newSymbol);
3332     const auto &details{symbol->get<SubprogramDetails>()};
3333     auto &newDetails{newSymbol.get<SubprogramDetails>()};
3334     newDetails.set_moduleInterface(*symbol);
3335     for (const Symbol *dummyArg : details.dummyArgs()) {
3336       if (!dummyArg) {
3337         newDetails.add_alternateReturn();
3338       } else if (Symbol * copy{currScope().CopySymbol(*dummyArg)}) {
3339         newDetails.add_dummyArg(*copy);
3340       }
3341     }
3342     if (details.isFunction()) {
3343       currScope().erase(symbol->name());
3344       newDetails.set_result(*currScope().CopySymbol(details.result()));
3345       funcInfoStack_.emplace_back(); // just to be popped later
3346     }
3347   }
3348   return true;
3349 }
3350 
3351 // A subprogram or interface declared with SUBROUTINE or FUNCTION
3352 bool SubprogramVisitor::BeginSubprogram(
3353     const parser::Name &name, Symbol::Flag subpFlag, bool hasModulePrefix) {
3354   if (hasModulePrefix && currScope().IsGlobal()) { // C1547
3355     Say(name,
3356         "'%s' is a MODULE procedure which must be declared within a "
3357         "MODULE or SUBMODULE"_err_en_US);
3358     return false;
3359   }
3360   Symbol *moduleInterface{nullptr};
3361   if (hasModulePrefix && !inInterfaceBlock()) {
3362     moduleInterface = FindSymbol(currScope(), name);
3363     if (IsSeparateModuleProcedureInterface(moduleInterface)) {
3364       // Subprogram is MODULE FUNCTION or MODULE SUBROUTINE with an interface
3365       // previously defined in the same scope.
3366       currScope().erase(moduleInterface->name());
3367     } else {
3368       moduleInterface = nullptr;
3369     }
3370     if (!moduleInterface) {
3371       moduleInterface = FindSymbol(currScope().parent(), name);
3372       if (!IsSeparateModuleProcedureInterface(moduleInterface)) {
3373         Say(name,
3374             "'%s' was not declared a separate module procedure"_err_en_US);
3375         return false;
3376       }
3377     }
3378   }
3379   Symbol &newSymbol{PushSubprogramScope(name, subpFlag)};
3380   if (moduleInterface) {
3381     newSymbol.get<SubprogramDetails>().set_moduleInterface(*moduleInterface);
3382     if (moduleInterface->attrs().test(Attr::PRIVATE)) {
3383       newSymbol.attrs().set(Attr::PRIVATE);
3384     } else if (moduleInterface->attrs().test(Attr::PUBLIC)) {
3385       newSymbol.attrs().set(Attr::PUBLIC);
3386     }
3387   }
3388   if (IsFunction(currScope())) {
3389     funcInfoStack_.emplace_back();
3390   }
3391   return true;
3392 }
3393 
3394 void SubprogramVisitor::EndSubprogram() {
3395   if (IsFunction(currScope())) {
3396     funcInfoStack_.pop_back();
3397   }
3398   PopScope();
3399 }
3400 
3401 bool SubprogramVisitor::HandlePreviousCalls(
3402     const parser::Name &name, Symbol &symbol, Symbol::Flag subpFlag) {
3403   if (const auto *proc{symbol.detailsIf<ProcEntityDetails>()}; proc &&
3404       !proc->isDummy() &&
3405       !symbol.attrs().HasAny(Attrs{Attr::INTRINSIC, Attr::POINTER})) {
3406     // There's a symbol created for previous calls to this subprogram or
3407     // ENTRY's name.  We have to replace that symbol in situ to avoid the
3408     // obligation to rewrite symbol pointers in the parse tree.
3409     if (!symbol.test(subpFlag)) {
3410       Say2(name,
3411           subpFlag == Symbol::Flag::Function
3412               ? "'%s' was previously called as a subroutine"_err_en_US
3413               : "'%s' was previously called as a function"_err_en_US,
3414           symbol, "Previous call of '%s'"_en_US);
3415     }
3416     EntityDetails entity;
3417     if (proc->type()) {
3418       entity.set_type(*proc->type());
3419     }
3420     symbol.details() = std::move(entity);
3421     return true;
3422   } else {
3423     return symbol.has<UnknownDetails>() || symbol.has<SubprogramNameDetails>();
3424   }
3425 }
3426 
3427 void SubprogramVisitor::CheckExtantProc(
3428     const parser::Name &name, Symbol::Flag subpFlag) {
3429   if (auto *prev{FindSymbol(name)}) {
3430     if (IsDummy(*prev)) {
3431     } else if (inInterfaceBlock() && currScope() != prev->owner()) {
3432       // Procedures in an INTERFACE block do not resolve to symbols
3433       // in scopes between the global scope and the current scope.
3434     } else if (!HandlePreviousCalls(name, *prev, subpFlag)) {
3435       SayAlreadyDeclared(name, *prev);
3436     }
3437   }
3438 }
3439 
3440 Symbol &SubprogramVisitor::PushSubprogramScope(
3441     const parser::Name &name, Symbol::Flag subpFlag) {
3442   auto *symbol{GetSpecificFromGeneric(name)};
3443   if (!symbol) {
3444     CheckExtantProc(name, subpFlag);
3445     symbol = &MakeSymbol(name, SubprogramDetails{});
3446   }
3447   symbol->set(subpFlag);
3448   symbol->ReplaceName(name.source);
3449   PushScope(Scope::Kind::Subprogram, symbol);
3450   auto &details{symbol->get<SubprogramDetails>()};
3451   if (inInterfaceBlock()) {
3452     details.set_isInterface();
3453     if (isAbstract()) {
3454       symbol->attrs().set(Attr::ABSTRACT);
3455     } else {
3456       MakeExternal(*symbol);
3457     }
3458     if (isGeneric()) {
3459       Symbol &genericSymbol{GetGenericSymbol()};
3460       if (genericSymbol.has<GenericDetails>()) {
3461         genericSymbol.get<GenericDetails>().AddSpecificProc(
3462             *symbol, name.source);
3463       } else {
3464         CHECK(context().HasError(genericSymbol));
3465       }
3466     }
3467     set_inheritFromParent(false);
3468   }
3469   FindSymbol(name)->set(subpFlag); // PushScope() created symbol
3470   return *symbol;
3471 }
3472 
3473 void SubprogramVisitor::PushBlockDataScope(const parser::Name &name) {
3474   if (auto *prev{FindSymbol(name)}) {
3475     if (prev->attrs().test(Attr::EXTERNAL) && prev->has<ProcEntityDetails>()) {
3476       if (prev->test(Symbol::Flag::Subroutine) ||
3477           prev->test(Symbol::Flag::Function)) {
3478         Say2(name, "BLOCK DATA '%s' has been called"_err_en_US, *prev,
3479             "Previous call of '%s'"_en_US);
3480       }
3481       EraseSymbol(name);
3482     }
3483   }
3484   if (name.source.empty()) {
3485     // Don't let unnamed BLOCK DATA conflict with unnamed PROGRAM
3486     PushScope(Scope::Kind::BlockData, nullptr);
3487   } else {
3488     PushScope(Scope::Kind::BlockData, &MakeSymbol(name, SubprogramDetails{}));
3489   }
3490 }
3491 
3492 // If name is a generic, return specific subprogram with the same name.
3493 Symbol *SubprogramVisitor::GetSpecificFromGeneric(const parser::Name &name) {
3494   if (auto *symbol{FindSymbol(name)}) {
3495     if (auto *details{symbol->detailsIf<GenericDetails>()}) {
3496       // found generic, want subprogram
3497       auto *specific{details->specific()};
3498       if (!specific) {
3499         specific =
3500             &currScope().MakeSymbol(name.source, Attrs{}, SubprogramDetails{});
3501         if (details->derivedType()) {
3502           // A specific procedure with the same name as a derived type
3503           SayAlreadyDeclared(name, *details->derivedType());
3504         } else {
3505           details->set_specific(Resolve(name, *specific));
3506         }
3507       } else if (isGeneric()) {
3508         SayAlreadyDeclared(name, *specific);
3509       }
3510       if (!specific->has<SubprogramDetails>()) {
3511         specific->set_details(SubprogramDetails{});
3512       }
3513       return specific;
3514     }
3515   }
3516   return nullptr;
3517 }
3518 
3519 // DeclarationVisitor implementation
3520 
3521 bool DeclarationVisitor::BeginDecl() {
3522   BeginDeclTypeSpec();
3523   BeginArraySpec();
3524   return BeginAttrs();
3525 }
3526 void DeclarationVisitor::EndDecl() {
3527   EndDeclTypeSpec();
3528   EndArraySpec();
3529   EndAttrs();
3530 }
3531 
3532 bool DeclarationVisitor::CheckUseError(const parser::Name &name) {
3533   const auto *details{
3534       name.symbol ? name.symbol->detailsIf<UseErrorDetails>() : nullptr};
3535   if (!details) {
3536     return false;
3537   }
3538   Message &msg{Say(name, "Reference to '%s' is ambiguous"_err_en_US)};
3539   for (const auto &[location, module] : details->occurrences()) {
3540     msg.Attach(location, "'%s' was use-associated from module '%s'"_en_US,
3541         name.source, module->GetName().value());
3542   }
3543   context().SetError(*name.symbol);
3544   return true;
3545 }
3546 
3547 // Report error if accessibility of symbol doesn't match isPrivate.
3548 void DeclarationVisitor::CheckAccessibility(
3549     const SourceName &name, bool isPrivate, Symbol &symbol) {
3550   if (symbol.attrs().test(Attr::PRIVATE) != isPrivate) {
3551     Say2(name,
3552         "'%s' does not have the same accessibility as its previous declaration"_err_en_US,
3553         symbol, "Previous declaration of '%s'"_en_US);
3554   }
3555 }
3556 
3557 void DeclarationVisitor::Post(const parser::TypeDeclarationStmt &) {
3558   if (!GetAttrs().HasAny({Attr::POINTER, Attr::ALLOCATABLE})) { // C702
3559     if (const auto *typeSpec{GetDeclTypeSpec()}) {
3560       if (typeSpec->category() == DeclTypeSpec::Character) {
3561         if (typeSpec->characterTypeSpec().length().isDeferred()) {
3562           Say("The type parameter LEN cannot be deferred without"
3563               " the POINTER or ALLOCATABLE attribute"_err_en_US);
3564         }
3565       } else if (const DerivedTypeSpec * derivedSpec{typeSpec->AsDerived()}) {
3566         for (const auto &pair : derivedSpec->parameters()) {
3567           if (pair.second.isDeferred()) {
3568             Say(currStmtSource().value(),
3569                 "The value of type parameter '%s' cannot be deferred"
3570                 " without the POINTER or ALLOCATABLE attribute"_err_en_US,
3571                 pair.first);
3572           }
3573         }
3574       }
3575     }
3576   }
3577   EndDecl();
3578 }
3579 
3580 void DeclarationVisitor::Post(const parser::DimensionStmt::Declaration &x) {
3581   DeclareObjectEntity(std::get<parser::Name>(x.t));
3582 }
3583 void DeclarationVisitor::Post(const parser::CodimensionDecl &x) {
3584   DeclareObjectEntity(std::get<parser::Name>(x.t));
3585 }
3586 
3587 bool DeclarationVisitor::Pre(const parser::Initialization &) {
3588   // Defer inspection of initializers to Initialization() so that the
3589   // symbol being initialized will be available within the initialization
3590   // expression.
3591   return false;
3592 }
3593 
3594 void DeclarationVisitor::Post(const parser::EntityDecl &x) {
3595   const auto &name{std::get<parser::ObjectName>(x.t)};
3596   Attrs attrs{attrs_ ? HandleSaveName(name.source, *attrs_) : Attrs{}};
3597   Symbol &symbol{DeclareUnknownEntity(name, attrs)};
3598   symbol.ReplaceName(name.source);
3599   if (const auto &init{std::get<std::optional<parser::Initialization>>(x.t)}) {
3600     if (ConvertToObjectEntity(symbol)) {
3601       Initialization(name, *init, false);
3602     }
3603   } else if (attrs.test(Attr::PARAMETER)) { // C882, C883
3604     Say(name, "Missing initialization for parameter '%s'"_err_en_US);
3605   }
3606 }
3607 
3608 void DeclarationVisitor::Post(const parser::PointerDecl &x) {
3609   const auto &name{std::get<parser::Name>(x.t)};
3610   if (const auto &deferredShapeSpecs{
3611           std::get<std::optional<parser::DeferredShapeSpecList>>(x.t)}) {
3612     CHECK(arraySpec().empty());
3613     BeginArraySpec();
3614     set_arraySpec(AnalyzeDeferredShapeSpecList(context(), *deferredShapeSpecs));
3615     Symbol &symbol{DeclareObjectEntity(name, Attrs{Attr::POINTER})};
3616     symbol.ReplaceName(name.source);
3617     EndArraySpec();
3618   } else {
3619     Symbol &symbol{DeclareUnknownEntity(name, Attrs{Attr::POINTER})};
3620     symbol.ReplaceName(name.source);
3621   }
3622 }
3623 
3624 bool DeclarationVisitor::Pre(const parser::BindEntity &x) {
3625   auto kind{std::get<parser::BindEntity::Kind>(x.t)};
3626   auto &name{std::get<parser::Name>(x.t)};
3627   Symbol *symbol;
3628   if (kind == parser::BindEntity::Kind::Object) {
3629     symbol = &HandleAttributeStmt(Attr::BIND_C, name);
3630   } else {
3631     symbol = &MakeCommonBlockSymbol(name);
3632     symbol->attrs().set(Attr::BIND_C);
3633   }
3634   SetBindNameOn(*symbol);
3635   return false;
3636 }
3637 bool DeclarationVisitor::Pre(const parser::OldParameterStmt &x) {
3638   inOldStyleParameterStmt_ = true;
3639   Walk(x.v);
3640   inOldStyleParameterStmt_ = false;
3641   return false;
3642 }
3643 bool DeclarationVisitor::Pre(const parser::NamedConstantDef &x) {
3644   auto &name{std::get<parser::NamedConstant>(x.t).v};
3645   auto &symbol{HandleAttributeStmt(Attr::PARAMETER, name)};
3646   if (!ConvertToObjectEntity(symbol) ||
3647       symbol.test(Symbol::Flag::CrayPointer) ||
3648       symbol.test(Symbol::Flag::CrayPointee)) {
3649     SayWithDecl(
3650         name, symbol, "PARAMETER attribute not allowed on '%s'"_err_en_US);
3651     return false;
3652   }
3653   const auto &expr{std::get<parser::ConstantExpr>(x.t)};
3654   auto &details{symbol.get<ObjectEntityDetails>()};
3655   if (inOldStyleParameterStmt_) {
3656     // non-standard extension PARAMETER statement (no parentheses)
3657     Walk(expr);
3658     auto folded{EvaluateExpr(expr)};
3659     if (details.type()) {
3660       SayWithDecl(name, symbol,
3661           "Alternative style PARAMETER '%s' must not already have an explicit type"_err_en_US);
3662     } else if (folded) {
3663       auto at{expr.thing.value().source};
3664       if (evaluate::IsActuallyConstant(*folded)) {
3665         if (const auto *type{currScope().GetType(*folded)}) {
3666           if (type->IsPolymorphic()) {
3667             Say(at, "The expression must not be polymorphic"_err_en_US);
3668           } else if (auto shape{ToArraySpec(
3669                          GetFoldingContext(), evaluate::GetShape(*folded))}) {
3670             // The type of the named constant is assumed from the expression.
3671             details.set_type(*type);
3672             details.set_init(std::move(*folded));
3673             details.set_shape(std::move(*shape));
3674           } else {
3675             Say(at, "The expression must have constant shape"_err_en_US);
3676           }
3677         } else {
3678           Say(at, "The expression must have a known type"_err_en_US);
3679         }
3680       } else {
3681         Say(at, "The expression must be a constant of known type"_err_en_US);
3682       }
3683     }
3684   } else {
3685     // standard-conforming PARAMETER statement (with parentheses)
3686     ApplyImplicitRules(symbol);
3687     Walk(expr);
3688     if (auto converted{EvaluateNonPointerInitializer(
3689             symbol, expr, expr.thing.value().source)}) {
3690       details.set_init(std::move(*converted));
3691     }
3692   }
3693   return false;
3694 }
3695 bool DeclarationVisitor::Pre(const parser::NamedConstant &x) {
3696   const parser::Name &name{x.v};
3697   if (!FindSymbol(name)) {
3698     Say(name, "Named constant '%s' not found"_err_en_US);
3699   } else {
3700     CheckUseError(name);
3701   }
3702   return false;
3703 }
3704 
3705 bool DeclarationVisitor::Pre(const parser::Enumerator &enumerator) {
3706   const parser::Name &name{std::get<parser::NamedConstant>(enumerator.t).v};
3707   Symbol *symbol{FindSymbol(name)};
3708   if (symbol && !symbol->has<UnknownDetails>()) {
3709     // Contrary to named constants appearing in a PARAMETER statement,
3710     // enumerator names should not have their type, dimension or any other
3711     // attributes defined before they are declared in the enumerator statement,
3712     // with the exception of accessibility.
3713     // This is not explicitly forbidden by the standard, but they are scalars
3714     // which type is left for the compiler to chose, so do not let users try to
3715     // tamper with that.
3716     SayAlreadyDeclared(name, *symbol);
3717     symbol = nullptr;
3718   } else {
3719     // Enumerators are treated as PARAMETER (section 7.6 paragraph (4))
3720     symbol = &MakeSymbol(name, Attrs{Attr::PARAMETER}, ObjectEntityDetails{});
3721     symbol->SetType(context().MakeNumericType(
3722         TypeCategory::Integer, evaluate::CInteger::kind));
3723   }
3724 
3725   if (auto &init{std::get<std::optional<parser::ScalarIntConstantExpr>>(
3726           enumerator.t)}) {
3727     Walk(*init); // Resolve names in expression before evaluation.
3728     if (auto value{EvaluateInt64(context(), *init)}) {
3729       // Cast all init expressions to C_INT so that they can then be
3730       // safely incremented (see 7.6 Note 2).
3731       enumerationState_.value = static_cast<int>(*value);
3732     } else {
3733       Say(name,
3734           "Enumerator value could not be computed "
3735           "from the given expression"_err_en_US);
3736       // Prevent resolution of next enumerators value
3737       enumerationState_.value = std::nullopt;
3738     }
3739   }
3740 
3741   if (symbol) {
3742     if (enumerationState_.value) {
3743       symbol->get<ObjectEntityDetails>().set_init(SomeExpr{
3744           evaluate::Expr<evaluate::CInteger>{*enumerationState_.value}});
3745     } else {
3746       context().SetError(*symbol);
3747     }
3748   }
3749 
3750   if (enumerationState_.value) {
3751     (*enumerationState_.value)++;
3752   }
3753   return false;
3754 }
3755 
3756 void DeclarationVisitor::Post(const parser::EnumDef &) {
3757   enumerationState_ = EnumeratorState{};
3758 }
3759 
3760 bool DeclarationVisitor::Pre(const parser::AccessSpec &x) {
3761   Attr attr{AccessSpecToAttr(x)};
3762   if (!NonDerivedTypeScope().IsModule()) { // C817
3763     Say(currStmtSource().value(),
3764         "%s attribute may only appear in the specification part of a module"_err_en_US,
3765         EnumToString(attr));
3766   }
3767   CheckAndSet(attr);
3768   return false;
3769 }
3770 
3771 bool DeclarationVisitor::Pre(const parser::AsynchronousStmt &x) {
3772   return HandleAttributeStmt(Attr::ASYNCHRONOUS, x.v);
3773 }
3774 bool DeclarationVisitor::Pre(const parser::ContiguousStmt &x) {
3775   return HandleAttributeStmt(Attr::CONTIGUOUS, x.v);
3776 }
3777 bool DeclarationVisitor::Pre(const parser::ExternalStmt &x) {
3778   HandleAttributeStmt(Attr::EXTERNAL, x.v);
3779   for (const auto &name : x.v) {
3780     auto *symbol{FindSymbol(name)};
3781     if (!ConvertToProcEntity(*symbol)) {
3782       SayWithDecl(
3783           name, *symbol, "EXTERNAL attribute not allowed on '%s'"_err_en_US);
3784     } else if (symbol->attrs().test(Attr::INTRINSIC)) { // C840
3785       Say(symbol->name(),
3786           "Symbol '%s' cannot have both INTRINSIC and EXTERNAL attributes"_err_en_US,
3787           symbol->name());
3788     }
3789   }
3790   return false;
3791 }
3792 bool DeclarationVisitor::Pre(const parser::IntentStmt &x) {
3793   auto &intentSpec{std::get<parser::IntentSpec>(x.t)};
3794   auto &names{std::get<std::list<parser::Name>>(x.t)};
3795   return CheckNotInBlock("INTENT") && // C1107
3796       HandleAttributeStmt(IntentSpecToAttr(intentSpec), names);
3797 }
3798 bool DeclarationVisitor::Pre(const parser::IntrinsicStmt &x) {
3799   HandleAttributeStmt(Attr::INTRINSIC, x.v);
3800   for (const auto &name : x.v) {
3801     auto &symbol{DEREF(FindSymbol(name))};
3802     if (!ConvertToProcEntity(symbol)) {
3803       SayWithDecl(
3804           name, symbol, "INTRINSIC attribute not allowed on '%s'"_err_en_US);
3805     } else if (symbol.attrs().test(Attr::EXTERNAL)) { // C840
3806       Say(symbol.name(),
3807           "Symbol '%s' cannot have both EXTERNAL and INTRINSIC attributes"_err_en_US,
3808           symbol.name());
3809     } else if (symbol.GetType()) {
3810       // These warnings are worded so that they should make sense in either
3811       // order.
3812       Say(symbol.name(),
3813           "Explicit type declaration ignored for intrinsic function '%s'"_warn_en_US,
3814           symbol.name())
3815           .Attach(name.source,
3816               "INTRINSIC statement for explicitly-typed '%s'"_en_US,
3817               name.source);
3818     }
3819   }
3820   return false;
3821 }
3822 bool DeclarationVisitor::Pre(const parser::OptionalStmt &x) {
3823   return CheckNotInBlock("OPTIONAL") && // C1107
3824       HandleAttributeStmt(Attr::OPTIONAL, x.v);
3825 }
3826 bool DeclarationVisitor::Pre(const parser::ProtectedStmt &x) {
3827   return HandleAttributeStmt(Attr::PROTECTED, x.v);
3828 }
3829 bool DeclarationVisitor::Pre(const parser::ValueStmt &x) {
3830   return CheckNotInBlock("VALUE") && // C1107
3831       HandleAttributeStmt(Attr::VALUE, x.v);
3832 }
3833 bool DeclarationVisitor::Pre(const parser::VolatileStmt &x) {
3834   return HandleAttributeStmt(Attr::VOLATILE, x.v);
3835 }
3836 // Handle a statement that sets an attribute on a list of names.
3837 bool DeclarationVisitor::HandleAttributeStmt(
3838     Attr attr, const std::list<parser::Name> &names) {
3839   for (const auto &name : names) {
3840     HandleAttributeStmt(attr, name);
3841   }
3842   return false;
3843 }
3844 Symbol &DeclarationVisitor::HandleAttributeStmt(
3845     Attr attr, const parser::Name &name) {
3846   if (attr == Attr::INTRINSIC && !IsIntrinsic(name.source, std::nullopt)) {
3847     Say(name.source, "'%s' is not a known intrinsic procedure"_err_en_US);
3848   }
3849   auto *symbol{FindInScope(name)};
3850   if (attr == Attr::ASYNCHRONOUS || attr == Attr::VOLATILE) {
3851     // these can be set on a symbol that is host-assoc or use-assoc
3852     if (!symbol &&
3853         (currScope().kind() == Scope::Kind::Subprogram ||
3854             currScope().kind() == Scope::Kind::Block)) {
3855       if (auto *hostSymbol{FindSymbol(name)}) {
3856         symbol = &MakeHostAssocSymbol(name, *hostSymbol);
3857       }
3858     }
3859   } else if (symbol && symbol->has<UseDetails>()) {
3860     Say(currStmtSource().value(),
3861         "Cannot change %s attribute on use-associated '%s'"_err_en_US,
3862         EnumToString(attr), name.source);
3863     return *symbol;
3864   }
3865   if (!symbol) {
3866     symbol = &MakeSymbol(name, EntityDetails{});
3867   }
3868   symbol->attrs().set(attr);
3869   symbol->attrs() = HandleSaveName(name.source, symbol->attrs());
3870   return *symbol;
3871 }
3872 // C1107
3873 bool DeclarationVisitor::CheckNotInBlock(const char *stmt) {
3874   if (currScope().kind() == Scope::Kind::Block) {
3875     Say(MessageFormattedText{
3876         "%s statement is not allowed in a BLOCK construct"_err_en_US, stmt});
3877     return false;
3878   } else {
3879     return true;
3880   }
3881 }
3882 
3883 void DeclarationVisitor::Post(const parser::ObjectDecl &x) {
3884   CHECK(objectDeclAttr_);
3885   const auto &name{std::get<parser::ObjectName>(x.t)};
3886   DeclareObjectEntity(name, Attrs{*objectDeclAttr_});
3887 }
3888 
3889 // Declare an entity not yet known to be an object or proc.
3890 Symbol &DeclarationVisitor::DeclareUnknownEntity(
3891     const parser::Name &name, Attrs attrs) {
3892   if (!arraySpec().empty() || !coarraySpec().empty()) {
3893     return DeclareObjectEntity(name, attrs);
3894   } else {
3895     Symbol &symbol{DeclareEntity<EntityDetails>(name, attrs)};
3896     if (auto *type{GetDeclTypeSpec()}) {
3897       SetType(name, *type);
3898     }
3899     charInfo_.length.reset();
3900     SetBindNameOn(symbol);
3901     if (symbol.attrs().test(Attr::EXTERNAL)) {
3902       ConvertToProcEntity(symbol);
3903     }
3904     return symbol;
3905   }
3906 }
3907 
3908 bool DeclarationVisitor::HasCycle(
3909     const Symbol &procSymbol, const ProcInterface &interface) {
3910   SourceOrderedSymbolSet procsInCycle;
3911   procsInCycle.insert(procSymbol);
3912   const ProcInterface *thisInterface{&interface};
3913   bool haveInterface{true};
3914   while (haveInterface) {
3915     haveInterface = false;
3916     if (const Symbol * interfaceSymbol{thisInterface->symbol()}) {
3917       if (procsInCycle.count(*interfaceSymbol) > 0) {
3918         for (const auto &procInCycle : procsInCycle) {
3919           Say(procInCycle->name(),
3920               "The interface for procedure '%s' is recursively "
3921               "defined"_err_en_US,
3922               procInCycle->name());
3923           context().SetError(*procInCycle);
3924         }
3925         return true;
3926       } else if (const auto *procDetails{
3927                      interfaceSymbol->detailsIf<ProcEntityDetails>()}) {
3928         haveInterface = true;
3929         thisInterface = &procDetails->interface();
3930         procsInCycle.insert(*interfaceSymbol);
3931       }
3932     }
3933   }
3934   return false;
3935 }
3936 
3937 Symbol &DeclarationVisitor::DeclareProcEntity(
3938     const parser::Name &name, Attrs attrs, const ProcInterface &interface) {
3939   Symbol &symbol{DeclareEntity<ProcEntityDetails>(name, attrs)};
3940   if (auto *details{symbol.detailsIf<ProcEntityDetails>()}) {
3941     if (details->IsInterfaceSet()) {
3942       SayWithDecl(name, symbol,
3943           "The interface for procedure '%s' has already been "
3944           "declared"_err_en_US);
3945       context().SetError(symbol);
3946     } else if (HasCycle(symbol, interface)) {
3947       return symbol;
3948     } else if (interface.type()) {
3949       symbol.set(Symbol::Flag::Function);
3950     } else if (interface.symbol()) {
3951       if (interface.symbol()->test(Symbol::Flag::Function)) {
3952         symbol.set(Symbol::Flag::Function);
3953       } else if (interface.symbol()->test(Symbol::Flag::Subroutine)) {
3954         symbol.set(Symbol::Flag::Subroutine);
3955       }
3956     }
3957     details->set_interface(interface);
3958     SetBindNameOn(symbol);
3959     SetPassNameOn(symbol);
3960   }
3961   return symbol;
3962 }
3963 
3964 Symbol &DeclarationVisitor::DeclareObjectEntity(
3965     const parser::Name &name, Attrs attrs) {
3966   Symbol &symbol{DeclareEntity<ObjectEntityDetails>(name, attrs)};
3967   if (auto *details{symbol.detailsIf<ObjectEntityDetails>()}) {
3968     if (auto *type{GetDeclTypeSpec()}) {
3969       SetType(name, *type);
3970     }
3971     if (!arraySpec().empty()) {
3972       if (details->IsArray()) {
3973         if (!context().HasError(symbol)) {
3974           Say(name,
3975               "The dimensions of '%s' have already been declared"_err_en_US);
3976           context().SetError(symbol);
3977         }
3978       } else {
3979         details->set_shape(arraySpec());
3980       }
3981     }
3982     if (!coarraySpec().empty()) {
3983       if (details->IsCoarray()) {
3984         if (!context().HasError(symbol)) {
3985           Say(name,
3986               "The codimensions of '%s' have already been declared"_err_en_US);
3987           context().SetError(symbol);
3988         }
3989       } else {
3990         details->set_coshape(coarraySpec());
3991       }
3992     }
3993     SetBindNameOn(symbol);
3994   }
3995   ClearArraySpec();
3996   ClearCoarraySpec();
3997   charInfo_.length.reset();
3998   return symbol;
3999 }
4000 
4001 void DeclarationVisitor::Post(const parser::IntegerTypeSpec &x) {
4002   SetDeclTypeSpec(MakeNumericType(TypeCategory::Integer, x.v));
4003 }
4004 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Real &x) {
4005   SetDeclTypeSpec(MakeNumericType(TypeCategory::Real, x.kind));
4006 }
4007 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Complex &x) {
4008   SetDeclTypeSpec(MakeNumericType(TypeCategory::Complex, x.kind));
4009 }
4010 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Logical &x) {
4011   SetDeclTypeSpec(MakeLogicalType(x.kind));
4012 }
4013 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Character &) {
4014   if (!charInfo_.length) {
4015     charInfo_.length = ParamValue{1, common::TypeParamAttr::Len};
4016   }
4017   if (!charInfo_.kind) {
4018     charInfo_.kind =
4019         KindExpr{context().GetDefaultKind(TypeCategory::Character)};
4020   }
4021   SetDeclTypeSpec(currScope().MakeCharacterType(
4022       std::move(*charInfo_.length), std::move(*charInfo_.kind)));
4023   charInfo_ = {};
4024 }
4025 void DeclarationVisitor::Post(const parser::CharSelector::LengthAndKind &x) {
4026   charInfo_.kind = EvaluateSubscriptIntExpr(x.kind);
4027   std::optional<std::int64_t> intKind{ToInt64(charInfo_.kind)};
4028   if (intKind &&
4029       !evaluate::IsValidKindOfIntrinsicType(
4030           TypeCategory::Character, *intKind)) { // C715, C719
4031     Say(currStmtSource().value(),
4032         "KIND value (%jd) not valid for CHARACTER"_err_en_US, *intKind);
4033     charInfo_.kind = std::nullopt; // prevent further errors
4034   }
4035   if (x.length) {
4036     charInfo_.length = GetParamValue(*x.length, common::TypeParamAttr::Len);
4037   }
4038 }
4039 void DeclarationVisitor::Post(const parser::CharLength &x) {
4040   if (const auto *length{std::get_if<std::uint64_t>(&x.u)}) {
4041     charInfo_.length = ParamValue{
4042         static_cast<ConstantSubscript>(*length), common::TypeParamAttr::Len};
4043   } else {
4044     charInfo_.length = GetParamValue(
4045         std::get<parser::TypeParamValue>(x.u), common::TypeParamAttr::Len);
4046   }
4047 }
4048 void DeclarationVisitor::Post(const parser::LengthSelector &x) {
4049   if (const auto *param{std::get_if<parser::TypeParamValue>(&x.u)}) {
4050     charInfo_.length = GetParamValue(*param, common::TypeParamAttr::Len);
4051   }
4052 }
4053 
4054 bool DeclarationVisitor::Pre(const parser::KindParam &x) {
4055   if (const auto *kind{std::get_if<
4056           parser::Scalar<parser::Integer<parser::Constant<parser::Name>>>>(
4057           &x.u)}) {
4058     const parser::Name &name{kind->thing.thing.thing};
4059     if (!FindSymbol(name)) {
4060       Say(name, "Parameter '%s' not found"_err_en_US);
4061     }
4062   }
4063   return false;
4064 }
4065 
4066 bool DeclarationVisitor::Pre(const parser::DeclarationTypeSpec::Type &) {
4067   CHECK(GetDeclTypeSpecCategory() == DeclTypeSpec::Category::TypeDerived);
4068   return true;
4069 }
4070 
4071 void DeclarationVisitor::Post(const parser::DeclarationTypeSpec::Type &type) {
4072   const parser::Name &derivedName{std::get<parser::Name>(type.derived.t)};
4073   if (const Symbol * derivedSymbol{derivedName.symbol}) {
4074     CheckForAbstractType(*derivedSymbol); // C706
4075   }
4076 }
4077 
4078 bool DeclarationVisitor::Pre(const parser::DeclarationTypeSpec::Class &) {
4079   SetDeclTypeSpecCategory(DeclTypeSpec::Category::ClassDerived);
4080   return true;
4081 }
4082 
4083 void DeclarationVisitor::Post(
4084     const parser::DeclarationTypeSpec::Class &parsedClass) {
4085   const auto &typeName{std::get<parser::Name>(parsedClass.derived.t)};
4086   if (auto spec{ResolveDerivedType(typeName)};
4087       spec && !IsExtensibleType(&*spec)) { // C705
4088     SayWithDecl(typeName, *typeName.symbol,
4089         "Non-extensible derived type '%s' may not be used with CLASS"
4090         " keyword"_err_en_US);
4091   }
4092 }
4093 
4094 void DeclarationVisitor::Post(const parser::DerivedTypeSpec &x) {
4095   const auto &typeName{std::get<parser::Name>(x.t)};
4096   auto spec{ResolveDerivedType(typeName)};
4097   if (!spec) {
4098     return;
4099   }
4100   bool seenAnyName{false};
4101   for (const auto &typeParamSpec :
4102       std::get<std::list<parser::TypeParamSpec>>(x.t)) {
4103     const auto &optKeyword{
4104         std::get<std::optional<parser::Keyword>>(typeParamSpec.t)};
4105     std::optional<SourceName> name;
4106     if (optKeyword) {
4107       seenAnyName = true;
4108       name = optKeyword->v.source;
4109     } else if (seenAnyName) {
4110       Say(typeName.source, "Type parameter value must have a name"_err_en_US);
4111       continue;
4112     }
4113     const auto &value{std::get<parser::TypeParamValue>(typeParamSpec.t)};
4114     // The expressions in a derived type specifier whose values define
4115     // non-defaulted type parameters are evaluated (folded) in the enclosing
4116     // scope.  The KIND/LEN distinction is resolved later in
4117     // DerivedTypeSpec::CookParameters().
4118     ParamValue param{GetParamValue(value, common::TypeParamAttr::Kind)};
4119     if (!param.isExplicit() || param.GetExplicit()) {
4120       spec->AddRawParamValue(optKeyword, std::move(param));
4121     }
4122   }
4123 
4124   // The DerivedTypeSpec *spec is used initially as a search key.
4125   // If it turns out to have the same name and actual parameter
4126   // value expressions as another DerivedTypeSpec in the current
4127   // scope does, then we'll use that extant spec; otherwise, when this
4128   // spec is distinct from all derived types previously instantiated
4129   // in the current scope, this spec will be moved into that collection.
4130   const auto &dtDetails{spec->typeSymbol().get<DerivedTypeDetails>()};
4131   auto category{GetDeclTypeSpecCategory()};
4132   if (dtDetails.isForwardReferenced()) {
4133     DeclTypeSpec &type{currScope().MakeDerivedType(category, std::move(*spec))};
4134     SetDeclTypeSpec(type);
4135     return;
4136   }
4137   // Normalize parameters to produce a better search key.
4138   spec->CookParameters(GetFoldingContext());
4139   if (!spec->MightBeParameterized()) {
4140     spec->EvaluateParameters(context());
4141   }
4142   if (const DeclTypeSpec *
4143       extant{currScope().FindInstantiatedDerivedType(*spec, category)}) {
4144     // This derived type and parameter expressions (if any) are already present
4145     // in this scope.
4146     SetDeclTypeSpec(*extant);
4147   } else {
4148     DeclTypeSpec &type{currScope().MakeDerivedType(category, std::move(*spec))};
4149     DerivedTypeSpec &derived{type.derivedTypeSpec()};
4150     if (derived.MightBeParameterized() &&
4151         currScope().IsParameterizedDerivedType()) {
4152       // Defer instantiation; use the derived type's definition's scope.
4153       derived.set_scope(DEREF(spec->typeSymbol().scope()));
4154     } else if (&currScope() == spec->typeSymbol().scope()) {
4155       // Direct recursive use of a type in the definition of one of its
4156       // components: defer instantiation
4157     } else {
4158       auto restorer{
4159           GetFoldingContext().messages().SetLocation(currStmtSource().value())};
4160       derived.Instantiate(currScope());
4161     }
4162     SetDeclTypeSpec(type);
4163   }
4164   // Capture the DerivedTypeSpec in the parse tree for use in building
4165   // structure constructor expressions.
4166   x.derivedTypeSpec = &GetDeclTypeSpec()->derivedTypeSpec();
4167 }
4168 
4169 void DeclarationVisitor::Post(const parser::DeclarationTypeSpec::Record &rec) {
4170   const auto &typeName{rec.v};
4171   if (auto spec{ResolveDerivedType(typeName)}) {
4172     spec->CookParameters(GetFoldingContext());
4173     spec->EvaluateParameters(context());
4174     if (const DeclTypeSpec *
4175         extant{currScope().FindInstantiatedDerivedType(
4176             *spec, DeclTypeSpec::TypeDerived)}) {
4177       SetDeclTypeSpec(*extant);
4178     } else {
4179       Say(typeName.source, "%s is not a known STRUCTURE"_err_en_US,
4180           typeName.source);
4181     }
4182   }
4183 }
4184 
4185 // The descendents of DerivedTypeDef in the parse tree are visited directly
4186 // in this Pre() routine so that recursive use of the derived type can be
4187 // supported in the components.
4188 bool DeclarationVisitor::Pre(const parser::DerivedTypeDef &x) {
4189   auto &stmt{std::get<parser::Statement<parser::DerivedTypeStmt>>(x.t)};
4190   Walk(stmt);
4191   Walk(std::get<std::list<parser::Statement<parser::TypeParamDefStmt>>>(x.t));
4192   auto &scope{currScope()};
4193   CHECK(scope.symbol());
4194   CHECK(scope.symbol()->scope() == &scope);
4195   auto &details{scope.symbol()->get<DerivedTypeDetails>()};
4196   details.set_isForwardReferenced(false);
4197   std::set<SourceName> paramNames;
4198   for (auto &paramName : std::get<std::list<parser::Name>>(stmt.statement.t)) {
4199     details.add_paramName(paramName.source);
4200     auto *symbol{FindInScope(scope, paramName)};
4201     if (!symbol) {
4202       Say(paramName,
4203           "No definition found for type parameter '%s'"_err_en_US); // C742
4204       // No symbol for a type param.  Create one and mark it as containing an
4205       // error to improve subsequent semantic processing
4206       BeginAttrs();
4207       Symbol *typeParam{MakeTypeSymbol(
4208           paramName, TypeParamDetails{common::TypeParamAttr::Len})};
4209       context().SetError(*typeParam);
4210       EndAttrs();
4211     } else if (!symbol->has<TypeParamDetails>()) {
4212       Say2(paramName, "'%s' is not defined as a type parameter"_err_en_US,
4213           *symbol, "Definition of '%s'"_en_US); // C741
4214     }
4215     if (!paramNames.insert(paramName.source).second) {
4216       Say(paramName,
4217           "Duplicate type parameter name: '%s'"_err_en_US); // C731
4218     }
4219   }
4220   for (const auto &[name, symbol] : currScope()) {
4221     if (symbol->has<TypeParamDetails>() && !paramNames.count(name)) {
4222       SayDerivedType(name,
4223           "'%s' is not a type parameter of this derived type"_err_en_US,
4224           currScope()); // C741
4225     }
4226   }
4227   Walk(std::get<std::list<parser::Statement<parser::PrivateOrSequence>>>(x.t));
4228   const auto &componentDefs{
4229       std::get<std::list<parser::Statement<parser::ComponentDefStmt>>>(x.t)};
4230   Walk(componentDefs);
4231   if (derivedTypeInfo_.sequence) {
4232     details.set_sequence(true);
4233     if (componentDefs.empty()) { // C740
4234       Say(stmt.source,
4235           "A sequence type must have at least one component"_err_en_US);
4236     }
4237     if (!details.paramNames().empty()) { // C740
4238       Say(stmt.source,
4239           "A sequence type may not have type parameters"_err_en_US);
4240     }
4241     if (derivedTypeInfo_.extends) { // C735
4242       Say(stmt.source,
4243           "A sequence type may not have the EXTENDS attribute"_err_en_US);
4244     }
4245   }
4246   Walk(std::get<std::optional<parser::TypeBoundProcedurePart>>(x.t));
4247   Walk(std::get<parser::Statement<parser::EndTypeStmt>>(x.t));
4248   derivedTypeInfo_ = {};
4249   PopScope();
4250   return false;
4251 }
4252 
4253 bool DeclarationVisitor::Pre(const parser::DerivedTypeStmt &) {
4254   return BeginAttrs();
4255 }
4256 void DeclarationVisitor::Post(const parser::DerivedTypeStmt &x) {
4257   auto &name{std::get<parser::Name>(x.t)};
4258   // Resolve the EXTENDS() clause before creating the derived
4259   // type's symbol to foil attempts to recursively extend a type.
4260   auto *extendsName{derivedTypeInfo_.extends};
4261   std::optional<DerivedTypeSpec> extendsType{
4262       ResolveExtendsType(name, extendsName)};
4263   auto &symbol{MakeSymbol(name, GetAttrs(), DerivedTypeDetails{})};
4264   symbol.ReplaceName(name.source);
4265   derivedTypeInfo_.type = &symbol;
4266   PushScope(Scope::Kind::DerivedType, &symbol);
4267   if (extendsType) {
4268     // Declare the "parent component"; private if the type is.
4269     // Any symbol stored in the EXTENDS() clause is temporarily
4270     // hidden so that a new symbol can be created for the parent
4271     // component without producing spurious errors about already
4272     // existing.
4273     const Symbol &extendsSymbol{extendsType->typeSymbol()};
4274     auto restorer{common::ScopedSet(extendsName->symbol, nullptr)};
4275     if (OkToAddComponent(*extendsName, &extendsSymbol)) {
4276       auto &comp{DeclareEntity<ObjectEntityDetails>(*extendsName, Attrs{})};
4277       comp.attrs().set(
4278           Attr::PRIVATE, extendsSymbol.attrs().test(Attr::PRIVATE));
4279       comp.set(Symbol::Flag::ParentComp);
4280       DeclTypeSpec &type{currScope().MakeDerivedType(
4281           DeclTypeSpec::TypeDerived, std::move(*extendsType))};
4282       type.derivedTypeSpec().set_scope(*extendsSymbol.scope());
4283       comp.SetType(type);
4284       DerivedTypeDetails &details{symbol.get<DerivedTypeDetails>()};
4285       details.add_component(comp);
4286     }
4287   }
4288   EndAttrs();
4289 }
4290 
4291 void DeclarationVisitor::Post(const parser::TypeParamDefStmt &x) {
4292   auto *type{GetDeclTypeSpec()};
4293   auto attr{std::get<common::TypeParamAttr>(x.t)};
4294   for (auto &decl : std::get<std::list<parser::TypeParamDecl>>(x.t)) {
4295     auto &name{std::get<parser::Name>(decl.t)};
4296     if (Symbol * symbol{MakeTypeSymbol(name, TypeParamDetails{attr})}) {
4297       SetType(name, *type);
4298       if (auto &init{
4299               std::get<std::optional<parser::ScalarIntConstantExpr>>(decl.t)}) {
4300         if (auto maybeExpr{EvaluateNonPointerInitializer(
4301                 *symbol, *init, init->thing.thing.thing.value().source)}) {
4302           if (auto *intExpr{std::get_if<SomeIntExpr>(&maybeExpr->u)}) {
4303             symbol->get<TypeParamDetails>().set_init(std::move(*intExpr));
4304           }
4305         }
4306       }
4307     }
4308   }
4309   EndDecl();
4310 }
4311 bool DeclarationVisitor::Pre(const parser::TypeAttrSpec::Extends &x) {
4312   if (derivedTypeInfo_.extends) {
4313     Say(currStmtSource().value(),
4314         "Attribute 'EXTENDS' cannot be used more than once"_err_en_US);
4315   } else {
4316     derivedTypeInfo_.extends = &x.v;
4317   }
4318   return false;
4319 }
4320 
4321 bool DeclarationVisitor::Pre(const parser::PrivateStmt &) {
4322   if (!currScope().parent().IsModule()) {
4323     Say("PRIVATE is only allowed in a derived type that is"
4324         " in a module"_err_en_US); // C766
4325   } else if (derivedTypeInfo_.sawContains) {
4326     derivedTypeInfo_.privateBindings = true;
4327   } else if (!derivedTypeInfo_.privateComps) {
4328     derivedTypeInfo_.privateComps = true;
4329   } else {
4330     Say("PRIVATE may not appear more than once in"
4331         " derived type components"_warn_en_US); // C738
4332   }
4333   return false;
4334 }
4335 bool DeclarationVisitor::Pre(const parser::SequenceStmt &) {
4336   if (derivedTypeInfo_.sequence) {
4337     Say("SEQUENCE may not appear more than once in"
4338         " derived type components"_warn_en_US); // C738
4339   }
4340   derivedTypeInfo_.sequence = true;
4341   return false;
4342 }
4343 void DeclarationVisitor::Post(const parser::ComponentDecl &x) {
4344   const auto &name{std::get<parser::Name>(x.t)};
4345   auto attrs{GetAttrs()};
4346   if (derivedTypeInfo_.privateComps &&
4347       !attrs.HasAny({Attr::PUBLIC, Attr::PRIVATE})) {
4348     attrs.set(Attr::PRIVATE);
4349   }
4350   if (const auto *declType{GetDeclTypeSpec()}) {
4351     if (const auto *derived{declType->AsDerived()}) {
4352       if (!attrs.HasAny({Attr::POINTER, Attr::ALLOCATABLE})) {
4353         if (derivedTypeInfo_.type == &derived->typeSymbol()) { // C744
4354           Say("Recursive use of the derived type requires "
4355               "POINTER or ALLOCATABLE"_err_en_US);
4356         }
4357       }
4358       // TODO: This would be more appropriate in CheckDerivedType()
4359       if (auto it{FindCoarrayUltimateComponent(*derived)}) { // C748
4360         std::string ultimateName{it.BuildResultDesignatorName()};
4361         // Strip off the leading "%"
4362         if (ultimateName.length() > 1) {
4363           ultimateName.erase(0, 1);
4364           if (attrs.HasAny({Attr::POINTER, Attr::ALLOCATABLE})) {
4365             evaluate::AttachDeclaration(
4366                 Say(name.source,
4367                     "A component with a POINTER or ALLOCATABLE attribute may "
4368                     "not "
4369                     "be of a type with a coarray ultimate component (named "
4370                     "'%s')"_err_en_US,
4371                     ultimateName),
4372                 derived->typeSymbol());
4373           }
4374           if (!arraySpec().empty() || !coarraySpec().empty()) {
4375             evaluate::AttachDeclaration(
4376                 Say(name.source,
4377                     "An array or coarray component may not be of a type with a "
4378                     "coarray ultimate component (named '%s')"_err_en_US,
4379                     ultimateName),
4380                 derived->typeSymbol());
4381           }
4382         }
4383       }
4384     }
4385   }
4386   if (OkToAddComponent(name)) {
4387     auto &symbol{DeclareObjectEntity(name, attrs)};
4388     if (symbol.has<ObjectEntityDetails>()) {
4389       if (auto &init{std::get<std::optional<parser::Initialization>>(x.t)}) {
4390         Initialization(name, *init, true);
4391       }
4392     }
4393     currScope().symbol()->get<DerivedTypeDetails>().add_component(symbol);
4394   }
4395   ClearArraySpec();
4396   ClearCoarraySpec();
4397 }
4398 void DeclarationVisitor::Post(const parser::FillDecl &x) {
4399   // Replace "%FILL" with a distinct generated name
4400   const auto &name{std::get<parser::Name>(x.t)};
4401   const_cast<SourceName &>(name.source) = context().GetTempName(currScope());
4402   if (OkToAddComponent(name)) {
4403     auto &symbol{DeclareObjectEntity(name, GetAttrs())};
4404     currScope().symbol()->get<DerivedTypeDetails>().add_component(symbol);
4405   }
4406   ClearArraySpec();
4407 }
4408 bool DeclarationVisitor::Pre(const parser::ProcedureDeclarationStmt &) {
4409   CHECK(!interfaceName_);
4410   return BeginDecl();
4411 }
4412 void DeclarationVisitor::Post(const parser::ProcedureDeclarationStmt &) {
4413   interfaceName_ = nullptr;
4414   EndDecl();
4415 }
4416 bool DeclarationVisitor::Pre(const parser::DataComponentDefStmt &x) {
4417   // Overrides parse tree traversal so as to handle attributes first,
4418   // so POINTER & ALLOCATABLE enable forward references to derived types.
4419   Walk(std::get<std::list<parser::ComponentAttrSpec>>(x.t));
4420   set_allowForwardReferenceToDerivedType(
4421       GetAttrs().HasAny({Attr::POINTER, Attr::ALLOCATABLE}));
4422   Walk(std::get<parser::DeclarationTypeSpec>(x.t));
4423   set_allowForwardReferenceToDerivedType(false);
4424   if (derivedTypeInfo_.sequence) { // C740
4425     if (const auto *declType{GetDeclTypeSpec()}) {
4426       if (!declType->AsIntrinsic() && !declType->IsSequenceType()) {
4427         if (GetAttrs().test(Attr::POINTER) &&
4428             context().IsEnabled(common::LanguageFeature::PointerInSeqType)) {
4429           if (context().ShouldWarn(common::LanguageFeature::PointerInSeqType)) {
4430             Say("A sequence type data component that is a pointer to a non-sequence type is not standard"_port_en_US);
4431           }
4432         } else {
4433           Say("A sequence type data component must either be of an intrinsic type or a derived sequence type"_err_en_US);
4434         }
4435       }
4436     }
4437   }
4438   Walk(std::get<std::list<parser::ComponentOrFill>>(x.t));
4439   return false;
4440 }
4441 bool DeclarationVisitor::Pre(const parser::ProcComponentDefStmt &) {
4442   CHECK(!interfaceName_);
4443   return true;
4444 }
4445 void DeclarationVisitor::Post(const parser::ProcComponentDefStmt &) {
4446   interfaceName_ = nullptr;
4447 }
4448 bool DeclarationVisitor::Pre(const parser::ProcPointerInit &x) {
4449   if (auto *name{std::get_if<parser::Name>(&x.u)}) {
4450     return !NameIsKnownOrIntrinsic(*name);
4451   }
4452   return true;
4453 }
4454 void DeclarationVisitor::Post(const parser::ProcInterface &x) {
4455   if (auto *name{std::get_if<parser::Name>(&x.u)}) {
4456     interfaceName_ = name;
4457     NoteInterfaceName(*name);
4458   }
4459 }
4460 void DeclarationVisitor::Post(const parser::ProcDecl &x) {
4461   const auto &name{std::get<parser::Name>(x.t)};
4462   ProcInterface interface;
4463   if (interfaceName_) {
4464     interface.set_symbol(*interfaceName_->symbol);
4465   } else if (auto *type{GetDeclTypeSpec()}) {
4466     interface.set_type(*type);
4467   }
4468   auto attrs{HandleSaveName(name.source, GetAttrs())};
4469   DerivedTypeDetails *dtDetails{nullptr};
4470   if (Symbol * symbol{currScope().symbol()}) {
4471     dtDetails = symbol->detailsIf<DerivedTypeDetails>();
4472   }
4473   if (!dtDetails) {
4474     attrs.set(Attr::EXTERNAL);
4475   }
4476   Symbol &symbol{DeclareProcEntity(name, attrs, interface)};
4477   symbol.ReplaceName(name.source);
4478   if (dtDetails) {
4479     dtDetails->add_component(symbol);
4480   }
4481 }
4482 
4483 bool DeclarationVisitor::Pre(const parser::TypeBoundProcedurePart &) {
4484   derivedTypeInfo_.sawContains = true;
4485   return true;
4486 }
4487 
4488 // Resolve binding names from type-bound generics, saved in genericBindings_.
4489 void DeclarationVisitor::Post(const parser::TypeBoundProcedurePart &) {
4490   // track specifics seen for the current generic to detect duplicates:
4491   const Symbol *currGeneric{nullptr};
4492   std::set<SourceName> specifics;
4493   for (const auto &[generic, bindingName] : genericBindings_) {
4494     if (generic != currGeneric) {
4495       currGeneric = generic;
4496       specifics.clear();
4497     }
4498     auto [it, inserted]{specifics.insert(bindingName->source)};
4499     if (!inserted) {
4500       Say(*bindingName, // C773
4501           "Binding name '%s' was already specified for generic '%s'"_err_en_US,
4502           bindingName->source, generic->name())
4503           .Attach(*it, "Previous specification of '%s'"_en_US, *it);
4504       continue;
4505     }
4506     auto *symbol{FindInTypeOrParents(*bindingName)};
4507     if (!symbol) {
4508       Say(*bindingName, // C772
4509           "Binding name '%s' not found in this derived type"_err_en_US);
4510     } else if (!symbol->has<ProcBindingDetails>()) {
4511       SayWithDecl(*bindingName, *symbol, // C772
4512           "'%s' is not the name of a specific binding of this type"_err_en_US);
4513     } else {
4514       generic->get<GenericDetails>().AddSpecificProc(
4515           *symbol, bindingName->source);
4516     }
4517   }
4518   genericBindings_.clear();
4519 }
4520 
4521 void DeclarationVisitor::Post(const parser::ContainsStmt &) {
4522   if (derivedTypeInfo_.sequence) {
4523     Say("A sequence type may not have a CONTAINS statement"_err_en_US); // C740
4524   }
4525 }
4526 
4527 void DeclarationVisitor::Post(
4528     const parser::TypeBoundProcedureStmt::WithoutInterface &x) {
4529   if (GetAttrs().test(Attr::DEFERRED)) { // C783
4530     Say("DEFERRED is only allowed when an interface-name is provided"_err_en_US);
4531   }
4532   for (auto &declaration : x.declarations) {
4533     auto &bindingName{std::get<parser::Name>(declaration.t)};
4534     auto &optName{std::get<std::optional<parser::Name>>(declaration.t)};
4535     const parser::Name &procedureName{optName ? *optName : bindingName};
4536     Symbol *procedure{FindSymbol(procedureName)};
4537     if (!procedure) {
4538       procedure = NoteInterfaceName(procedureName);
4539     }
4540     if (auto *s{MakeTypeSymbol(bindingName, ProcBindingDetails{*procedure})}) {
4541       SetPassNameOn(*s);
4542       if (GetAttrs().test(Attr::DEFERRED)) {
4543         context().SetError(*s);
4544       }
4545     }
4546   }
4547 }
4548 
4549 void DeclarationVisitor::CheckBindings(
4550     const parser::TypeBoundProcedureStmt::WithoutInterface &tbps) {
4551   CHECK(currScope().IsDerivedType());
4552   for (auto &declaration : tbps.declarations) {
4553     auto &bindingName{std::get<parser::Name>(declaration.t)};
4554     if (Symbol * binding{FindInScope(bindingName)}) {
4555       if (auto *details{binding->detailsIf<ProcBindingDetails>()}) {
4556         const Symbol *procedure{FindSubprogram(details->symbol())};
4557         if (!CanBeTypeBoundProc(procedure)) {
4558           if (details->symbol().name() != binding->name()) {
4559             Say(binding->name(),
4560                 "The binding of '%s' ('%s') must be either an accessible "
4561                 "module procedure or an external procedure with "
4562                 "an explicit interface"_err_en_US,
4563                 binding->name(), details->symbol().name());
4564           } else {
4565             Say(binding->name(),
4566                 "'%s' must be either an accessible module procedure "
4567                 "or an external procedure with an explicit interface"_err_en_US,
4568                 binding->name());
4569           }
4570           context().SetError(*binding);
4571         }
4572       }
4573     }
4574   }
4575 }
4576 
4577 void DeclarationVisitor::Post(
4578     const parser::TypeBoundProcedureStmt::WithInterface &x) {
4579   if (!GetAttrs().test(Attr::DEFERRED)) { // C783
4580     Say("DEFERRED is required when an interface-name is provided"_err_en_US);
4581   }
4582   if (Symbol * interface{NoteInterfaceName(x.interfaceName)}) {
4583     for (auto &bindingName : x.bindingNames) {
4584       if (auto *s{
4585               MakeTypeSymbol(bindingName, ProcBindingDetails{*interface})}) {
4586         SetPassNameOn(*s);
4587         if (!GetAttrs().test(Attr::DEFERRED)) {
4588           context().SetError(*s);
4589         }
4590       }
4591     }
4592   }
4593 }
4594 
4595 void DeclarationVisitor::Post(const parser::FinalProcedureStmt &x) {
4596   if (currScope().IsDerivedType() && currScope().symbol()) {
4597     if (auto *details{currScope().symbol()->detailsIf<DerivedTypeDetails>()}) {
4598       for (const auto &subrName : x.v) {
4599         if (const auto *name{ResolveName(subrName)}) {
4600           auto pair{
4601               details->finals().emplace(name->source, DEREF(name->symbol))};
4602           if (!pair.second) { // C787
4603             Say(name->source,
4604                 "FINAL subroutine '%s' already appeared in this derived type"_err_en_US,
4605                 name->source)
4606                 .Attach(pair.first->first,
4607                     "earlier appearance of this FINAL subroutine"_en_US);
4608           }
4609         }
4610       }
4611     }
4612   }
4613 }
4614 
4615 bool DeclarationVisitor::Pre(const parser::TypeBoundGenericStmt &x) {
4616   const auto &accessSpec{std::get<std::optional<parser::AccessSpec>>(x.t)};
4617   const auto &genericSpec{std::get<Indirection<parser::GenericSpec>>(x.t)};
4618   const auto &bindingNames{std::get<std::list<parser::Name>>(x.t)};
4619   auto info{GenericSpecInfo{genericSpec.value()}};
4620   SourceName symbolName{info.symbolName()};
4621   bool isPrivate{accessSpec ? accessSpec->v == parser::AccessSpec::Kind::Private
4622                             : derivedTypeInfo_.privateBindings};
4623   auto *genericSymbol{FindInScope(symbolName)};
4624   if (genericSymbol) {
4625     if (!genericSymbol->has<GenericDetails>()) {
4626       genericSymbol = nullptr; // MakeTypeSymbol will report the error below
4627     }
4628   } else {
4629     // look in parent types:
4630     Symbol *inheritedSymbol{nullptr};
4631     for (const auto &name : GetAllNames(context(), symbolName)) {
4632       inheritedSymbol = currScope().FindComponent(SourceName{name});
4633       if (inheritedSymbol) {
4634         break;
4635       }
4636     }
4637     if (inheritedSymbol && inheritedSymbol->has<GenericDetails>()) {
4638       CheckAccessibility(symbolName, isPrivate, *inheritedSymbol); // C771
4639     }
4640   }
4641   if (genericSymbol) {
4642     CheckAccessibility(symbolName, isPrivate, *genericSymbol); // C771
4643   } else {
4644     genericSymbol = MakeTypeSymbol(symbolName, GenericDetails{});
4645     if (!genericSymbol) {
4646       return false;
4647     }
4648     if (isPrivate) {
4649       genericSymbol->attrs().set(Attr::PRIVATE);
4650     }
4651   }
4652   for (const parser::Name &bindingName : bindingNames) {
4653     genericBindings_.emplace(genericSymbol, &bindingName);
4654   }
4655   info.Resolve(genericSymbol);
4656   return false;
4657 }
4658 
4659 // DEC STRUCTUREs are handled thus to allow for nested definitions.
4660 bool DeclarationVisitor::Pre(const parser::StructureDef &def) {
4661   const auto &structureStatement{
4662       std::get<parser::Statement<parser::StructureStmt>>(def.t)};
4663   auto saveDerivedTypeInfo{derivedTypeInfo_};
4664   derivedTypeInfo_ = {};
4665   derivedTypeInfo_.isStructure = true;
4666   derivedTypeInfo_.sequence = true;
4667   Scope *previousStructure{nullptr};
4668   if (saveDerivedTypeInfo.isStructure) {
4669     previousStructure = &currScope();
4670     PopScope();
4671   }
4672   const parser::StructureStmt &structStmt{structureStatement.statement};
4673   const auto &name{std::get<std::optional<parser::Name>>(structStmt.t)};
4674   if (!name) {
4675     // Construct a distinct generated name for an anonymous structure
4676     auto &mutableName{const_cast<std::optional<parser::Name> &>(name)};
4677     mutableName.emplace(
4678         parser::Name{context().GetTempName(currScope()), nullptr});
4679   }
4680   auto &symbol{MakeSymbol(*name, DerivedTypeDetails{})};
4681   symbol.ReplaceName(name->source);
4682   symbol.get<DerivedTypeDetails>().set_sequence(true);
4683   symbol.get<DerivedTypeDetails>().set_isDECStructure(true);
4684   derivedTypeInfo_.type = &symbol;
4685   PushScope(Scope::Kind::DerivedType, &symbol);
4686   const auto &fields{std::get<std::list<parser::StructureField>>(def.t)};
4687   Walk(fields);
4688   PopScope();
4689   // Complete the definition
4690   DerivedTypeSpec derivedTypeSpec{symbol.name(), symbol};
4691   derivedTypeSpec.set_scope(DEREF(symbol.scope()));
4692   derivedTypeSpec.CookParameters(GetFoldingContext());
4693   derivedTypeSpec.EvaluateParameters(context());
4694   DeclTypeSpec &type{currScope().MakeDerivedType(
4695       DeclTypeSpec::TypeDerived, std::move(derivedTypeSpec))};
4696   type.derivedTypeSpec().Instantiate(currScope());
4697   // Restore previous structure definition context, if any
4698   derivedTypeInfo_ = saveDerivedTypeInfo;
4699   if (previousStructure) {
4700     PushScope(*previousStructure);
4701   }
4702   // Handle any entity declarations on the STRUCTURE statement
4703   const auto &decls{std::get<std::list<parser::EntityDecl>>(structStmt.t)};
4704   if (!decls.empty()) {
4705     BeginDecl();
4706     SetDeclTypeSpec(type);
4707     Walk(decls);
4708     EndDecl();
4709   }
4710   return false;
4711 }
4712 
4713 bool DeclarationVisitor::Pre(const parser::Union::UnionStmt &) {
4714   Say("UNION is not yet supported"_err_en_US); // TODO
4715   return true;
4716 }
4717 
4718 bool DeclarationVisitor::Pre(const parser::StructureField &x) {
4719   if (std::holds_alternative<parser::Statement<parser::DataComponentDefStmt>>(
4720           x.u)) {
4721     BeginDecl();
4722   }
4723   return true;
4724 }
4725 
4726 void DeclarationVisitor::Post(const parser::StructureField &x) {
4727   if (std::holds_alternative<parser::Statement<parser::DataComponentDefStmt>>(
4728           x.u)) {
4729     EndDecl();
4730   }
4731 }
4732 
4733 bool DeclarationVisitor::Pre(const parser::AllocateStmt &) {
4734   BeginDeclTypeSpec();
4735   return true;
4736 }
4737 void DeclarationVisitor::Post(const parser::AllocateStmt &) {
4738   EndDeclTypeSpec();
4739 }
4740 
4741 bool DeclarationVisitor::Pre(const parser::StructureConstructor &x) {
4742   auto &parsedType{std::get<parser::DerivedTypeSpec>(x.t)};
4743   const DeclTypeSpec *type{ProcessTypeSpec(parsedType)};
4744   if (!type) {
4745     return false;
4746   }
4747   const DerivedTypeSpec *spec{type->AsDerived()};
4748   const Scope *typeScope{spec ? spec->scope() : nullptr};
4749   if (!typeScope) {
4750     return false;
4751   }
4752 
4753   // N.B C7102 is implicitly enforced by having inaccessible types not
4754   // being found in resolution.
4755   // More constraints are enforced in expression.cpp so that they
4756   // can apply to structure constructors that have been converted
4757   // from misparsed function references.
4758   for (const auto &component :
4759       std::get<std::list<parser::ComponentSpec>>(x.t)) {
4760     // Visit the component spec expression, but not the keyword, since
4761     // we need to resolve its symbol in the scope of the derived type.
4762     Walk(std::get<parser::ComponentDataSource>(component.t));
4763     if (const auto &kw{std::get<std::optional<parser::Keyword>>(component.t)}) {
4764       FindInTypeOrParents(*typeScope, kw->v);
4765     }
4766   }
4767   return false;
4768 }
4769 
4770 bool DeclarationVisitor::Pre(const parser::BasedPointerStmt &x) {
4771   for (const parser::BasedPointer &bp : x.v) {
4772     const parser::ObjectName &pointerName{std::get<0>(bp.t)};
4773     const parser::ObjectName &pointeeName{std::get<1>(bp.t)};
4774     auto *pointer{FindSymbol(pointerName)};
4775     if (!pointer) {
4776       pointer = &MakeSymbol(pointerName, ObjectEntityDetails{});
4777     } else if (!ConvertToObjectEntity(*pointer) || IsNamedConstant(*pointer)) {
4778       SayWithDecl(pointerName, *pointer, "'%s' is not a variable"_err_en_US);
4779     } else if (pointer->Rank() > 0) {
4780       SayWithDecl(pointerName, *pointer,
4781           "Cray pointer '%s' must be a scalar"_err_en_US);
4782     } else if (pointer->test(Symbol::Flag::CrayPointee)) {
4783       Say(pointerName,
4784           "'%s' cannot be a Cray pointer as it is already a Cray pointee"_err_en_US);
4785     }
4786     pointer->set(Symbol::Flag::CrayPointer);
4787     const DeclTypeSpec &pointerType{MakeNumericType(TypeCategory::Integer,
4788         context().defaultKinds().subscriptIntegerKind())};
4789     const auto *type{pointer->GetType()};
4790     if (!type) {
4791       pointer->SetType(pointerType);
4792     } else if (*type != pointerType) {
4793       Say(pointerName.source, "Cray pointer '%s' must have type %s"_err_en_US,
4794           pointerName.source, pointerType.AsFortran());
4795     }
4796     if (ResolveName(pointeeName)) {
4797       Symbol &pointee{*pointeeName.symbol};
4798       if (pointee.has<UseDetails>()) {
4799         Say(pointeeName,
4800             "'%s' cannot be a Cray pointee as it is use-associated"_err_en_US);
4801         continue;
4802       } else if (!ConvertToObjectEntity(pointee) || IsNamedConstant(pointee)) {
4803         Say(pointeeName, "'%s' is not a variable"_err_en_US);
4804         continue;
4805       } else if (pointee.test(Symbol::Flag::CrayPointer)) {
4806         Say(pointeeName,
4807             "'%s' cannot be a Cray pointee as it is already a Cray pointer"_err_en_US);
4808       } else if (pointee.test(Symbol::Flag::CrayPointee)) {
4809         Say(pointeeName,
4810             "'%s' was already declared as a Cray pointee"_err_en_US);
4811       } else {
4812         pointee.set(Symbol::Flag::CrayPointee);
4813       }
4814       if (const auto *pointeeType{pointee.GetType()}) {
4815         if (const auto *derived{pointeeType->AsDerived()}) {
4816           if (!derived->typeSymbol().get<DerivedTypeDetails>().sequence()) {
4817             Say(pointeeName,
4818                 "Type of Cray pointee '%s' is a non-sequence derived type"_err_en_US);
4819           }
4820         }
4821       }
4822       // process the pointee array-spec, if present
4823       BeginArraySpec();
4824       Walk(std::get<std::optional<parser::ArraySpec>>(bp.t));
4825       const auto &spec{arraySpec()};
4826       if (!spec.empty()) {
4827         auto &details{pointee.get<ObjectEntityDetails>()};
4828         if (details.shape().empty()) {
4829           details.set_shape(spec);
4830         } else {
4831           SayWithDecl(pointeeName, pointee,
4832               "Array spec was already declared for '%s'"_err_en_US);
4833         }
4834       }
4835       ClearArraySpec();
4836       currScope().add_crayPointer(pointeeName.source, *pointer);
4837     }
4838   }
4839   return false;
4840 }
4841 
4842 bool DeclarationVisitor::Pre(const parser::NamelistStmt::Group &x) {
4843   if (!CheckNotInBlock("NAMELIST")) { // C1107
4844     return false;
4845   }
4846 
4847   NamelistDetails details;
4848   for (const auto &name : std::get<std::list<parser::Name>>(x.t)) {
4849     auto *symbol{FindSymbol(name)};
4850     if (!symbol) {
4851       symbol = &MakeSymbol(name, ObjectEntityDetails{});
4852       ApplyImplicitRules(*symbol);
4853     } else if (!ConvertToObjectEntity(*symbol)) {
4854       SayWithDecl(name, *symbol, "'%s' is not a variable"_err_en_US);
4855     }
4856     symbol->GetUltimate().set(Symbol::Flag::InNamelist);
4857     details.add_object(*symbol);
4858   }
4859 
4860   const auto &groupName{std::get<parser::Name>(x.t)};
4861   auto *groupSymbol{FindInScope(groupName)};
4862   if (!groupSymbol || !groupSymbol->has<NamelistDetails>()) {
4863     groupSymbol = &MakeSymbol(groupName, std::move(details));
4864     groupSymbol->ReplaceName(groupName.source);
4865   }
4866   groupSymbol->get<NamelistDetails>().add_objects(details.objects());
4867   return false;
4868 }
4869 
4870 bool DeclarationVisitor::Pre(const parser::IoControlSpec &x) {
4871   if (const auto *name{std::get_if<parser::Name>(&x.u)}) {
4872     auto *symbol{FindSymbol(*name)};
4873     if (!symbol) {
4874       Say(*name, "Namelist group '%s' not found"_err_en_US);
4875     } else if (!symbol->GetUltimate().has<NamelistDetails>()) {
4876       SayWithDecl(
4877           *name, *symbol, "'%s' is not the name of a namelist group"_err_en_US);
4878     }
4879   }
4880   return true;
4881 }
4882 
4883 bool DeclarationVisitor::Pre(const parser::CommonStmt::Block &x) {
4884   CheckNotInBlock("COMMON"); // C1107
4885   return true;
4886 }
4887 
4888 bool DeclarationVisitor::Pre(const parser::CommonBlockObject &) {
4889   BeginArraySpec();
4890   return true;
4891 }
4892 
4893 void DeclarationVisitor::Post(const parser::CommonBlockObject &x) {
4894   const auto &name{std::get<parser::Name>(x.t)};
4895   DeclareObjectEntity(name);
4896   auto pair{specPartState_.commonBlockObjects.insert(name.source)};
4897   if (!pair.second) {
4898     const SourceName &prev{*pair.first};
4899     Say2(name.source, "'%s' is already in a COMMON block"_err_en_US, prev,
4900         "Previous occurrence of '%s' in a COMMON block"_en_US);
4901   }
4902 }
4903 
4904 bool DeclarationVisitor::Pre(const parser::EquivalenceStmt &x) {
4905   // save equivalence sets to be processed after specification part
4906   if (CheckNotInBlock("EQUIVALENCE")) { // C1107
4907     for (const std::list<parser::EquivalenceObject> &set : x.v) {
4908       specPartState_.equivalenceSets.push_back(&set);
4909     }
4910   }
4911   return false; // don't implicitly declare names yet
4912 }
4913 
4914 void DeclarationVisitor::CheckEquivalenceSets() {
4915   EquivalenceSets equivSets{context()};
4916   inEquivalenceStmt_ = true;
4917   for (const auto *set : specPartState_.equivalenceSets) {
4918     const auto &source{set->front().v.value().source};
4919     if (set->size() <= 1) { // R871
4920       Say(source, "Equivalence set must have more than one object"_err_en_US);
4921     }
4922     for (const parser::EquivalenceObject &object : *set) {
4923       const auto &designator{object.v.value()};
4924       // The designator was not resolved when it was encountered so do it now.
4925       // AnalyzeExpr causes array sections to be changed to substrings as needed
4926       Walk(designator);
4927       if (AnalyzeExpr(context(), designator)) {
4928         equivSets.AddToSet(designator);
4929       }
4930     }
4931     equivSets.FinishSet(source);
4932   }
4933   inEquivalenceStmt_ = false;
4934   for (auto &set : equivSets.sets()) {
4935     if (!set.empty()) {
4936       currScope().add_equivalenceSet(std::move(set));
4937     }
4938   }
4939   specPartState_.equivalenceSets.clear();
4940 }
4941 
4942 bool DeclarationVisitor::Pre(const parser::SaveStmt &x) {
4943   if (x.v.empty()) {
4944     specPartState_.saveInfo.saveAll = currStmtSource();
4945     currScope().set_hasSAVE();
4946   } else {
4947     for (const parser::SavedEntity &y : x.v) {
4948       auto kind{std::get<parser::SavedEntity::Kind>(y.t)};
4949       const auto &name{std::get<parser::Name>(y.t)};
4950       if (kind == parser::SavedEntity::Kind::Common) {
4951         MakeCommonBlockSymbol(name);
4952         AddSaveName(specPartState_.saveInfo.commons, name.source);
4953       } else {
4954         HandleAttributeStmt(Attr::SAVE, name);
4955       }
4956     }
4957   }
4958   return false;
4959 }
4960 
4961 void DeclarationVisitor::CheckSaveStmts() {
4962   for (const SourceName &name : specPartState_.saveInfo.entities) {
4963     auto *symbol{FindInScope(name)};
4964     if (!symbol) {
4965       // error was reported
4966     } else if (specPartState_.saveInfo.saveAll) {
4967       // C889 - note that pgi, ifort, xlf do not enforce this constraint
4968       Say2(name,
4969           "Explicit SAVE of '%s' is redundant due to global SAVE statement"_err_en_US,
4970           *specPartState_.saveInfo.saveAll, "Global SAVE statement"_en_US);
4971     } else if (auto msg{CheckSaveAttr(*symbol)}) {
4972       Say(name, std::move(*msg));
4973       context().SetError(*symbol);
4974     } else {
4975       SetSaveAttr(*symbol);
4976     }
4977   }
4978   for (const SourceName &name : specPartState_.saveInfo.commons) {
4979     if (auto *symbol{currScope().FindCommonBlock(name)}) {
4980       auto &objects{symbol->get<CommonBlockDetails>().objects()};
4981       if (objects.empty()) {
4982         if (currScope().kind() != Scope::Kind::Block) {
4983           Say(name,
4984               "'%s' appears as a COMMON block in a SAVE statement but not in"
4985               " a COMMON statement"_err_en_US);
4986         } else { // C1108
4987           Say(name,
4988               "SAVE statement in BLOCK construct may not contain a"
4989               " common block name '%s'"_err_en_US);
4990         }
4991       } else {
4992         for (auto &object : symbol->get<CommonBlockDetails>().objects()) {
4993           SetSaveAttr(*object);
4994         }
4995       }
4996     }
4997   }
4998   if (specPartState_.saveInfo.saveAll) {
4999     // Apply SAVE attribute to applicable symbols
5000     for (auto pair : currScope()) {
5001       auto &symbol{*pair.second};
5002       if (!CheckSaveAttr(symbol)) {
5003         SetSaveAttr(symbol);
5004       }
5005     }
5006   }
5007   specPartState_.saveInfo = {};
5008 }
5009 
5010 // If SAVE attribute can't be set on symbol, return error message.
5011 std::optional<MessageFixedText> DeclarationVisitor::CheckSaveAttr(
5012     const Symbol &symbol) {
5013   if (IsDummy(symbol)) {
5014     return "SAVE attribute may not be applied to dummy argument '%s'"_err_en_US;
5015   } else if (symbol.IsFuncResult()) {
5016     return "SAVE attribute may not be applied to function result '%s'"_err_en_US;
5017   } else if (symbol.has<ProcEntityDetails>() &&
5018       !symbol.attrs().test(Attr::POINTER)) {
5019     return "Procedure '%s' with SAVE attribute must also have POINTER attribute"_err_en_US;
5020   } else if (IsAutomatic(symbol)) {
5021     return "SAVE attribute may not be applied to automatic data object '%s'"_err_en_US;
5022   } else {
5023     return std::nullopt;
5024   }
5025 }
5026 
5027 // Record SAVEd names in specPartState_.saveInfo.entities.
5028 Attrs DeclarationVisitor::HandleSaveName(const SourceName &name, Attrs attrs) {
5029   if (attrs.test(Attr::SAVE)) {
5030     AddSaveName(specPartState_.saveInfo.entities, name);
5031   }
5032   return attrs;
5033 }
5034 
5035 // Record a name in a set of those to be saved.
5036 void DeclarationVisitor::AddSaveName(
5037     std::set<SourceName> &set, const SourceName &name) {
5038   auto pair{set.insert(name)};
5039   if (!pair.second) {
5040     Say2(name, "SAVE attribute was already specified on '%s'"_warn_en_US,
5041         *pair.first, "Previous specification of SAVE attribute"_en_US);
5042   }
5043 }
5044 
5045 // Set the SAVE attribute on symbol unless it is implicitly saved anyway.
5046 void DeclarationVisitor::SetSaveAttr(Symbol &symbol) {
5047   if (!IsSaved(symbol)) {
5048     symbol.attrs().set(Attr::SAVE);
5049   }
5050 }
5051 
5052 // Check types of common block objects, now that they are known.
5053 void DeclarationVisitor::CheckCommonBlocks() {
5054   // check for empty common blocks
5055   for (const auto &pair : currScope().commonBlocks()) {
5056     const auto &symbol{*pair.second};
5057     if (symbol.get<CommonBlockDetails>().objects().empty() &&
5058         symbol.attrs().test(Attr::BIND_C)) {
5059       Say(symbol.name(),
5060           "'%s' appears as a COMMON block in a BIND statement but not in"
5061           " a COMMON statement"_err_en_US);
5062     }
5063   }
5064   // check objects in common blocks
5065   for (const auto &name : specPartState_.commonBlockObjects) {
5066     const auto *symbol{currScope().FindSymbol(name)};
5067     if (!symbol) {
5068       continue;
5069     }
5070     const auto &attrs{symbol->attrs()};
5071     if (attrs.test(Attr::ALLOCATABLE)) {
5072       Say(name,
5073           "ALLOCATABLE object '%s' may not appear in a COMMON block"_err_en_US);
5074     } else if (attrs.test(Attr::BIND_C)) {
5075       Say(name,
5076           "Variable '%s' with BIND attribute may not appear in a COMMON block"_err_en_US);
5077     } else if (IsDummy(*symbol)) {
5078       Say(name,
5079           "Dummy argument '%s' may not appear in a COMMON block"_err_en_US);
5080     } else if (symbol->IsFuncResult()) {
5081       Say(name,
5082           "Function result '%s' may not appear in a COMMON block"_err_en_US);
5083     } else if (const DeclTypeSpec * type{symbol->GetType()}) {
5084       if (type->category() == DeclTypeSpec::ClassStar) {
5085         Say(name,
5086             "Unlimited polymorphic pointer '%s' may not appear in a COMMON block"_err_en_US);
5087       } else if (const auto *derived{type->AsDerived()}) {
5088         auto &typeSymbol{derived->typeSymbol()};
5089         if (!typeSymbol.attrs().test(Attr::BIND_C) &&
5090             !typeSymbol.get<DerivedTypeDetails>().sequence()) {
5091           Say(name,
5092               "Derived type '%s' in COMMON block must have the BIND or"
5093               " SEQUENCE attribute"_err_en_US);
5094         }
5095         CheckCommonBlockDerivedType(name, typeSymbol);
5096       }
5097     }
5098   }
5099   specPartState_.commonBlockObjects = {};
5100 }
5101 
5102 Symbol &DeclarationVisitor::MakeCommonBlockSymbol(const parser::Name &name) {
5103   return Resolve(name, currScope().MakeCommonBlock(name.source));
5104 }
5105 Symbol &DeclarationVisitor::MakeCommonBlockSymbol(
5106     const std::optional<parser::Name> &name) {
5107   if (name) {
5108     return MakeCommonBlockSymbol(*name);
5109   } else {
5110     return MakeCommonBlockSymbol(parser::Name{});
5111   }
5112 }
5113 
5114 bool DeclarationVisitor::NameIsKnownOrIntrinsic(const parser::Name &name) {
5115   return FindSymbol(name) || HandleUnrestrictedSpecificIntrinsicFunction(name);
5116 }
5117 
5118 // Check if this derived type can be in a COMMON block.
5119 void DeclarationVisitor::CheckCommonBlockDerivedType(
5120     const SourceName &name, const Symbol &typeSymbol) {
5121   if (const auto *scope{typeSymbol.scope()}) {
5122     for (const auto &pair : *scope) {
5123       const Symbol &component{*pair.second};
5124       if (component.attrs().test(Attr::ALLOCATABLE)) {
5125         Say2(name,
5126             "Derived type variable '%s' may not appear in a COMMON block"
5127             " due to ALLOCATABLE component"_err_en_US,
5128             component.name(), "Component with ALLOCATABLE attribute"_en_US);
5129         return;
5130       }
5131       const auto *details{component.detailsIf<ObjectEntityDetails>()};
5132       if (component.test(Symbol::Flag::InDataStmt) ||
5133           (details && details->init())) {
5134         Say2(name,
5135             "Derived type variable '%s' may not appear in a COMMON block due to component with default initialization"_err_en_US,
5136             component.name(), "Component with default initialization"_en_US);
5137         return;
5138       }
5139       if (details) {
5140         if (const auto *type{details->type()}) {
5141           if (const auto *derived{type->AsDerived()}) {
5142             CheckCommonBlockDerivedType(name, derived->typeSymbol());
5143           }
5144         }
5145       }
5146     }
5147   }
5148 }
5149 
5150 bool DeclarationVisitor::HandleUnrestrictedSpecificIntrinsicFunction(
5151     const parser::Name &name) {
5152   if (auto interface{context().intrinsics().IsSpecificIntrinsicFunction(
5153           name.source.ToString())}) {
5154     // Unrestricted specific intrinsic function names (e.g., "cos")
5155     // are acceptable as procedure interfaces.  The presence of the
5156     // INTRINSIC flag will cause this symbol to have a complete interface
5157     // recreated for it later on demand, but capturing its result type here
5158     // will make GetType() return a correct result without having to
5159     // probe the intrinsics table again.
5160     Symbol &symbol{
5161         MakeSymbol(InclusiveScope(), name.source, Attrs{Attr::INTRINSIC})};
5162     CHECK(interface->functionResult.has_value());
5163     evaluate::DynamicType dyType{
5164         DEREF(interface->functionResult->GetTypeAndShape()).type()};
5165     CHECK(common::IsNumericTypeCategory(dyType.category()));
5166     const DeclTypeSpec &typeSpec{
5167         MakeNumericType(dyType.category(), dyType.kind())};
5168     ProcEntityDetails details;
5169     ProcInterface procInterface;
5170     procInterface.set_type(typeSpec);
5171     details.set_interface(procInterface);
5172     symbol.set_details(std::move(details));
5173     symbol.set(Symbol::Flag::Function);
5174     if (interface->IsElemental()) {
5175       symbol.attrs().set(Attr::ELEMENTAL);
5176     }
5177     if (interface->IsPure()) {
5178       symbol.attrs().set(Attr::PURE);
5179     }
5180     Resolve(name, symbol);
5181     return true;
5182   } else {
5183     return false;
5184   }
5185 }
5186 
5187 // Checks for all locality-specs: LOCAL, LOCAL_INIT, and SHARED
5188 bool DeclarationVisitor::PassesSharedLocalityChecks(
5189     const parser::Name &name, Symbol &symbol) {
5190   if (!IsVariableName(symbol)) {
5191     SayLocalMustBeVariable(name, symbol); // C1124
5192     return false;
5193   }
5194   if (symbol.owner() == currScope()) { // C1125 and C1126
5195     SayAlreadyDeclared(name, symbol);
5196     return false;
5197   }
5198   return true;
5199 }
5200 
5201 // Checks for locality-specs LOCAL and LOCAL_INIT
5202 bool DeclarationVisitor::PassesLocalityChecks(
5203     const parser::Name &name, Symbol &symbol) {
5204   if (IsAllocatable(symbol)) { // C1128
5205     SayWithDecl(name, symbol,
5206         "ALLOCATABLE variable '%s' not allowed in a locality-spec"_err_en_US);
5207     return false;
5208   }
5209   if (IsOptional(symbol)) { // C1128
5210     SayWithDecl(name, symbol,
5211         "OPTIONAL argument '%s' not allowed in a locality-spec"_err_en_US);
5212     return false;
5213   }
5214   if (IsIntentIn(symbol)) { // C1128
5215     SayWithDecl(name, symbol,
5216         "INTENT IN argument '%s' not allowed in a locality-spec"_err_en_US);
5217     return false;
5218   }
5219   if (IsFinalizable(symbol)) { // C1128
5220     SayWithDecl(name, symbol,
5221         "Finalizable variable '%s' not allowed in a locality-spec"_err_en_US);
5222     return false;
5223   }
5224   if (evaluate::IsCoarray(symbol)) { // C1128
5225     SayWithDecl(
5226         name, symbol, "Coarray '%s' not allowed in a locality-spec"_err_en_US);
5227     return false;
5228   }
5229   if (const DeclTypeSpec * type{symbol.GetType()}) {
5230     if (type->IsPolymorphic() && IsDummy(symbol) &&
5231         !IsPointer(symbol)) { // C1128
5232       SayWithDecl(name, symbol,
5233           "Nonpointer polymorphic argument '%s' not allowed in a "
5234           "locality-spec"_err_en_US);
5235       return false;
5236     }
5237   }
5238   if (IsAssumedSizeArray(symbol)) { // C1128
5239     SayWithDecl(name, symbol,
5240         "Assumed size array '%s' not allowed in a locality-spec"_err_en_US);
5241     return false;
5242   }
5243   if (std::optional<MessageFixedText> msg{
5244           WhyNotModifiable(symbol, currScope())}) {
5245     SayWithReason(name, symbol,
5246         "'%s' may not appear in a locality-spec because it is not "
5247         "definable"_err_en_US,
5248         std::move(*msg));
5249     return false;
5250   }
5251   return PassesSharedLocalityChecks(name, symbol);
5252 }
5253 
5254 Symbol &DeclarationVisitor::FindOrDeclareEnclosingEntity(
5255     const parser::Name &name) {
5256   Symbol *prev{FindSymbol(name)};
5257   if (!prev) {
5258     // Declare the name as an object in the enclosing scope so that
5259     // the name can't be repurposed there later as something else.
5260     prev = &MakeSymbol(InclusiveScope(), name.source, Attrs{});
5261     ConvertToObjectEntity(*prev);
5262     ApplyImplicitRules(*prev);
5263   }
5264   return *prev;
5265 }
5266 
5267 Symbol *DeclarationVisitor::DeclareLocalEntity(const parser::Name &name) {
5268   Symbol &prev{FindOrDeclareEnclosingEntity(name)};
5269   if (!PassesLocalityChecks(name, prev)) {
5270     return nullptr;
5271   }
5272   return &MakeHostAssocSymbol(name, prev);
5273 }
5274 
5275 Symbol *DeclarationVisitor::DeclareStatementEntity(
5276     const parser::DoVariable &doVar,
5277     const std::optional<parser::IntegerTypeSpec> &type) {
5278   const parser::Name &name{doVar.thing.thing};
5279   const DeclTypeSpec *declTypeSpec{nullptr};
5280   if (auto *prev{FindSymbol(name)}) {
5281     if (prev->owner() == currScope()) {
5282       SayAlreadyDeclared(name, *prev);
5283       return nullptr;
5284     }
5285     name.symbol = nullptr;
5286     declTypeSpec = prev->GetType();
5287   }
5288   Symbol &symbol{DeclareEntity<ObjectEntityDetails>(name, {})};
5289   if (!symbol.has<ObjectEntityDetails>()) {
5290     return nullptr; // error was reported in DeclareEntity
5291   }
5292   if (type) {
5293     declTypeSpec = ProcessTypeSpec(*type);
5294   }
5295   if (declTypeSpec) {
5296     // Subtlety: Don't let a "*length" specifier (if any is pending) affect the
5297     // declaration of this implied DO loop control variable.
5298     auto restorer{
5299         common::ScopedSet(charInfo_.length, std::optional<ParamValue>{})};
5300     SetType(name, *declTypeSpec);
5301   } else {
5302     ApplyImplicitRules(symbol);
5303   }
5304   Symbol *result{Resolve(name, &symbol)};
5305   AnalyzeExpr(context(), doVar); // enforce INTEGER type
5306   return result;
5307 }
5308 
5309 // Set the type of an entity or report an error.
5310 void DeclarationVisitor::SetType(
5311     const parser::Name &name, const DeclTypeSpec &type) {
5312   CHECK(name.symbol);
5313   auto &symbol{*name.symbol};
5314   if (charInfo_.length) { // Declaration has "*length" (R723)
5315     auto length{std::move(*charInfo_.length)};
5316     charInfo_.length.reset();
5317     if (type.category() == DeclTypeSpec::Character) {
5318       auto kind{type.characterTypeSpec().kind()};
5319       // Recurse with correct type.
5320       SetType(name,
5321           currScope().MakeCharacterType(std::move(length), std::move(kind)));
5322       return;
5323     } else { // C753
5324       Say(name,
5325           "A length specifier cannot be used to declare the non-character entity '%s'"_err_en_US);
5326     }
5327   }
5328   auto *prevType{symbol.GetType()};
5329   if (!prevType) {
5330     symbol.SetType(type);
5331   } else if (symbol.has<UseDetails>()) {
5332     // error recovery case, redeclaration of use-associated name
5333   } else if (HadForwardRef(symbol)) {
5334     // error recovery after use of host-associated name
5335   } else if (!symbol.test(Symbol::Flag::Implicit)) {
5336     SayWithDecl(
5337         name, symbol, "The type of '%s' has already been declared"_err_en_US);
5338     context().SetError(symbol);
5339   } else if (type != *prevType) {
5340     SayWithDecl(name, symbol,
5341         "The type of '%s' has already been implicitly declared"_err_en_US);
5342     context().SetError(symbol);
5343   } else {
5344     symbol.set(Symbol::Flag::Implicit, false);
5345   }
5346 }
5347 
5348 std::optional<DerivedTypeSpec> DeclarationVisitor::ResolveDerivedType(
5349     const parser::Name &name) {
5350   Symbol *symbol{FindSymbol(NonDerivedTypeScope(), name)};
5351   if (!symbol || symbol->has<UnknownDetails>()) {
5352     if (allowForwardReferenceToDerivedType()) {
5353       if (!symbol) {
5354         symbol = &MakeSymbol(InclusiveScope(), name.source, Attrs{});
5355         Resolve(name, *symbol);
5356       };
5357       DerivedTypeDetails details;
5358       details.set_isForwardReferenced(true);
5359       symbol->set_details(std::move(details));
5360     } else { // C732
5361       Say(name, "Derived type '%s' not found"_err_en_US);
5362       return std::nullopt;
5363     }
5364   }
5365   if (CheckUseError(name)) {
5366     return std::nullopt;
5367   }
5368   symbol = &symbol->GetUltimate();
5369   if (auto *details{symbol->detailsIf<GenericDetails>()}) {
5370     if (details->derivedType()) {
5371       symbol = details->derivedType();
5372     }
5373   }
5374   if (symbol->has<DerivedTypeDetails>()) {
5375     return DerivedTypeSpec{name.source, *symbol};
5376   } else {
5377     Say(name, "'%s' is not a derived type"_err_en_US);
5378     return std::nullopt;
5379   }
5380 }
5381 
5382 std::optional<DerivedTypeSpec> DeclarationVisitor::ResolveExtendsType(
5383     const parser::Name &typeName, const parser::Name *extendsName) {
5384   if (!extendsName) {
5385     return std::nullopt;
5386   } else if (typeName.source == extendsName->source) {
5387     Say(extendsName->source,
5388         "Derived type '%s' cannot extend itself"_err_en_US);
5389     return std::nullopt;
5390   } else {
5391     return ResolveDerivedType(*extendsName);
5392   }
5393 }
5394 
5395 Symbol *DeclarationVisitor::NoteInterfaceName(const parser::Name &name) {
5396   // The symbol is checked later by CheckExplicitInterface() and
5397   // CheckBindings().  It can be a forward reference.
5398   if (!NameIsKnownOrIntrinsic(name)) {
5399     Symbol &symbol{MakeSymbol(InclusiveScope(), name.source, Attrs{})};
5400     Resolve(name, symbol);
5401   }
5402   return name.symbol;
5403 }
5404 
5405 void DeclarationVisitor::CheckExplicitInterface(const parser::Name &name) {
5406   if (const Symbol * symbol{name.symbol}) {
5407     if (!context().HasError(*symbol) && !symbol->HasExplicitInterface()) {
5408       Say(name,
5409           "'%s' must be an abstract interface or a procedure with "
5410           "an explicit interface"_err_en_US,
5411           symbol->name());
5412     }
5413   }
5414 }
5415 
5416 // Create a symbol for a type parameter, component, or procedure binding in
5417 // the current derived type scope. Return false on error.
5418 Symbol *DeclarationVisitor::MakeTypeSymbol(
5419     const parser::Name &name, Details &&details) {
5420   return Resolve(name, MakeTypeSymbol(name.source, std::move(details)));
5421 }
5422 Symbol *DeclarationVisitor::MakeTypeSymbol(
5423     const SourceName &name, Details &&details) {
5424   Scope &derivedType{currScope()};
5425   CHECK(derivedType.IsDerivedType());
5426   if (auto *symbol{FindInScope(derivedType, name)}) { // C742
5427     Say2(name,
5428         "Type parameter, component, or procedure binding '%s'"
5429         " already defined in this type"_err_en_US,
5430         *symbol, "Previous definition of '%s'"_en_US);
5431     return nullptr;
5432   } else {
5433     auto attrs{GetAttrs()};
5434     // Apply binding-private-stmt if present and this is a procedure binding
5435     if (derivedTypeInfo_.privateBindings &&
5436         !attrs.HasAny({Attr::PUBLIC, Attr::PRIVATE}) &&
5437         std::holds_alternative<ProcBindingDetails>(details)) {
5438       attrs.set(Attr::PRIVATE);
5439     }
5440     Symbol &result{MakeSymbol(name, attrs, std::move(details))};
5441     if (result.has<TypeParamDetails>()) {
5442       derivedType.symbol()->get<DerivedTypeDetails>().add_paramDecl(result);
5443     }
5444     return &result;
5445   }
5446 }
5447 
5448 // Return true if it is ok to declare this component in the current scope.
5449 // Otherwise, emit an error and return false.
5450 bool DeclarationVisitor::OkToAddComponent(
5451     const parser::Name &name, const Symbol *extends) {
5452   for (const Scope *scope{&currScope()}; scope;) {
5453     CHECK(scope->IsDerivedType());
5454     if (auto *prev{FindInScope(*scope, name)}) {
5455       if (!context().HasError(*prev)) {
5456         parser::MessageFixedText msg;
5457         if (extends) {
5458           msg = "Type cannot be extended as it has a component named"
5459                 " '%s'"_err_en_US;
5460         } else if (prev->test(Symbol::Flag::ParentComp)) {
5461           msg = "'%s' is a parent type of this type and so cannot be"
5462                 " a component"_err_en_US;
5463         } else if (scope != &currScope()) {
5464           msg = "Component '%s' is already declared in a parent of this"
5465                 " derived type"_err_en_US;
5466         } else {
5467           msg = "Component '%s' is already declared in this"
5468                 " derived type"_err_en_US;
5469         }
5470         Say2(name, std::move(msg), *prev, "Previous declaration of '%s'"_en_US);
5471       }
5472       return false;
5473     }
5474     if (scope == &currScope() && extends) {
5475       // The parent component has not yet been added to the scope.
5476       scope = extends->scope();
5477     } else {
5478       scope = scope->GetDerivedTypeParent();
5479     }
5480   }
5481   return true;
5482 }
5483 
5484 ParamValue DeclarationVisitor::GetParamValue(
5485     const parser::TypeParamValue &x, common::TypeParamAttr attr) {
5486   return std::visit(
5487       common::visitors{
5488           [=](const parser::ScalarIntExpr &x) { // C704
5489             return ParamValue{EvaluateIntExpr(x), attr};
5490           },
5491           [=](const parser::Star &) { return ParamValue::Assumed(attr); },
5492           [=](const parser::TypeParamValue::Deferred &) {
5493             return ParamValue::Deferred(attr);
5494           },
5495       },
5496       x.u);
5497 }
5498 
5499 // ConstructVisitor implementation
5500 
5501 void ConstructVisitor::ResolveIndexName(
5502     const parser::ConcurrentControl &control) {
5503   const parser::Name &name{std::get<parser::Name>(control.t)};
5504   auto *prev{FindSymbol(name)};
5505   if (prev) {
5506     if (prev->owner().kind() == Scope::Kind::Forall ||
5507         prev->owner() == currScope()) {
5508       SayAlreadyDeclared(name, *prev);
5509       return;
5510     }
5511     name.symbol = nullptr;
5512   }
5513   auto &symbol{DeclareObjectEntity(name)};
5514   if (symbol.GetType()) {
5515     // type came from explicit type-spec
5516   } else if (!prev) {
5517     ApplyImplicitRules(symbol);
5518   } else {
5519     const Symbol &prevRoot{ResolveAssociations(*prev)};
5520     // prev could be host- use- or construct-associated with another symbol
5521     if (!prevRoot.has<ObjectEntityDetails>() &&
5522         !prevRoot.has<EntityDetails>()) {
5523       Say2(name, "Index name '%s' conflicts with existing identifier"_err_en_US,
5524           *prev, "Previous declaration of '%s'"_en_US);
5525       context().SetError(symbol);
5526       return;
5527     } else {
5528       if (const auto *type{prevRoot.GetType()}) {
5529         symbol.SetType(*type);
5530       }
5531       if (prevRoot.IsObjectArray()) {
5532         SayWithDecl(name, *prev, "Index variable '%s' is not scalar"_err_en_US);
5533         return;
5534       }
5535     }
5536   }
5537   EvaluateExpr(parser::Scalar{parser::Integer{common::Clone(name)}});
5538 }
5539 
5540 // We need to make sure that all of the index-names get declared before the
5541 // expressions in the loop control are evaluated so that references to the
5542 // index-names in the expressions are correctly detected.
5543 bool ConstructVisitor::Pre(const parser::ConcurrentHeader &header) {
5544   BeginDeclTypeSpec();
5545   Walk(std::get<std::optional<parser::IntegerTypeSpec>>(header.t));
5546   const auto &controls{
5547       std::get<std::list<parser::ConcurrentControl>>(header.t)};
5548   for (const auto &control : controls) {
5549     ResolveIndexName(control);
5550   }
5551   Walk(controls);
5552   Walk(std::get<std::optional<parser::ScalarLogicalExpr>>(header.t));
5553   EndDeclTypeSpec();
5554   return false;
5555 }
5556 
5557 bool ConstructVisitor::Pre(const parser::LocalitySpec::Local &x) {
5558   for (auto &name : x.v) {
5559     if (auto *symbol{DeclareLocalEntity(name)}) {
5560       symbol->set(Symbol::Flag::LocalityLocal);
5561     }
5562   }
5563   return false;
5564 }
5565 
5566 bool ConstructVisitor::Pre(const parser::LocalitySpec::LocalInit &x) {
5567   for (auto &name : x.v) {
5568     if (auto *symbol{DeclareLocalEntity(name)}) {
5569       symbol->set(Symbol::Flag::LocalityLocalInit);
5570     }
5571   }
5572   return false;
5573 }
5574 
5575 bool ConstructVisitor::Pre(const parser::LocalitySpec::Shared &x) {
5576   for (const auto &name : x.v) {
5577     if (!FindSymbol(name)) {
5578       Say(name,
5579           "Variable '%s' with SHARED locality implicitly declared"_warn_en_US);
5580     }
5581     Symbol &prev{FindOrDeclareEnclosingEntity(name)};
5582     if (PassesSharedLocalityChecks(name, prev)) {
5583       MakeHostAssocSymbol(name, prev).set(Symbol::Flag::LocalityShared);
5584     }
5585   }
5586   return false;
5587 }
5588 
5589 bool ConstructVisitor::Pre(const parser::AcSpec &x) {
5590   ProcessTypeSpec(x.type);
5591   Walk(x.values);
5592   return false;
5593 }
5594 
5595 // Section 19.4, paragraph 5 says that each ac-do-variable has the scope of the
5596 // enclosing ac-implied-do
5597 bool ConstructVisitor::Pre(const parser::AcImpliedDo &x) {
5598   auto &values{std::get<std::list<parser::AcValue>>(x.t)};
5599   auto &control{std::get<parser::AcImpliedDoControl>(x.t)};
5600   auto &type{std::get<std::optional<parser::IntegerTypeSpec>>(control.t)};
5601   auto &bounds{std::get<parser::AcImpliedDoControl::Bounds>(control.t)};
5602   // F'2018 has the scope of the implied DO variable covering the entire
5603   // implied DO production (19.4(5)), which seems wrong in cases where the name
5604   // of the implied DO variable appears in one of the bound expressions. Thus
5605   // this extension, which shrinks the scope of the variable to exclude the
5606   // expressions in the bounds.
5607   auto restore{BeginCheckOnIndexUseInOwnBounds(bounds.name)};
5608   Walk(bounds.lower);
5609   Walk(bounds.upper);
5610   Walk(bounds.step);
5611   EndCheckOnIndexUseInOwnBounds(restore);
5612   PushScope(Scope::Kind::ImpliedDos, nullptr);
5613   DeclareStatementEntity(bounds.name, type);
5614   Walk(values);
5615   PopScope();
5616   return false;
5617 }
5618 
5619 bool ConstructVisitor::Pre(const parser::DataImpliedDo &x) {
5620   auto &objects{std::get<std::list<parser::DataIDoObject>>(x.t)};
5621   auto &type{std::get<std::optional<parser::IntegerTypeSpec>>(x.t)};
5622   auto &bounds{std::get<parser::DataImpliedDo::Bounds>(x.t)};
5623   // See comment in Pre(AcImpliedDo) above.
5624   auto restore{BeginCheckOnIndexUseInOwnBounds(bounds.name)};
5625   Walk(bounds.lower);
5626   Walk(bounds.upper);
5627   Walk(bounds.step);
5628   EndCheckOnIndexUseInOwnBounds(restore);
5629   bool pushScope{currScope().kind() != Scope::Kind::ImpliedDos};
5630   if (pushScope) {
5631     PushScope(Scope::Kind::ImpliedDos, nullptr);
5632   }
5633   DeclareStatementEntity(bounds.name, type);
5634   Walk(objects);
5635   if (pushScope) {
5636     PopScope();
5637   }
5638   return false;
5639 }
5640 
5641 // Sets InDataStmt flag on a variable (or misidentified function) in a DATA
5642 // statement so that the predicate IsInitialized() will be true
5643 // during semantic analysis before the symbol's initializer is constructed.
5644 bool ConstructVisitor::Pre(const parser::DataIDoObject &x) {
5645   std::visit(
5646       common::visitors{
5647           [&](const parser::Scalar<Indirection<parser::Designator>> &y) {
5648             Walk(y.thing.value());
5649             const parser::Name &first{parser::GetFirstName(y.thing.value())};
5650             if (first.symbol) {
5651               first.symbol->set(Symbol::Flag::InDataStmt);
5652             }
5653           },
5654           [&](const Indirection<parser::DataImpliedDo> &y) { Walk(y.value()); },
5655       },
5656       x.u);
5657   return false;
5658 }
5659 
5660 bool ConstructVisitor::Pre(const parser::DataStmtObject &x) {
5661   std::visit(common::visitors{
5662                  [&](const Indirection<parser::Variable> &y) {
5663                    Walk(y.value());
5664                    const parser::Name &first{parser::GetFirstName(y.value())};
5665                    if (first.symbol) {
5666                      first.symbol->set(Symbol::Flag::InDataStmt);
5667                    }
5668                  },
5669                  [&](const parser::DataImpliedDo &y) {
5670                    PushScope(Scope::Kind::ImpliedDos, nullptr);
5671                    Walk(y);
5672                    PopScope();
5673                  },
5674              },
5675       x.u);
5676   return false;
5677 }
5678 
5679 bool ConstructVisitor::Pre(const parser::DataStmtValue &x) {
5680   const auto &data{std::get<parser::DataStmtConstant>(x.t)};
5681   auto &mutableData{const_cast<parser::DataStmtConstant &>(data)};
5682   if (auto *elem{parser::Unwrap<parser::ArrayElement>(mutableData)}) {
5683     if (const auto *name{std::get_if<parser::Name>(&elem->base.u)}) {
5684       if (const Symbol * symbol{FindSymbol(*name)}) {
5685         const Symbol &ultimate{symbol->GetUltimate()};
5686         if (ultimate.has<DerivedTypeDetails>()) {
5687           mutableData.u = elem->ConvertToStructureConstructor(
5688               DerivedTypeSpec{name->source, ultimate});
5689         }
5690       }
5691     }
5692   }
5693   return true;
5694 }
5695 
5696 bool ConstructVisitor::Pre(const parser::DoConstruct &x) {
5697   if (x.IsDoConcurrent()) {
5698     PushScope(Scope::Kind::Block, nullptr);
5699   }
5700   return true;
5701 }
5702 void ConstructVisitor::Post(const parser::DoConstruct &x) {
5703   if (x.IsDoConcurrent()) {
5704     PopScope();
5705   }
5706 }
5707 
5708 bool ConstructVisitor::Pre(const parser::ForallConstruct &) {
5709   PushScope(Scope::Kind::Forall, nullptr);
5710   return true;
5711 }
5712 void ConstructVisitor::Post(const parser::ForallConstruct &) { PopScope(); }
5713 bool ConstructVisitor::Pre(const parser::ForallStmt &) {
5714   PushScope(Scope::Kind::Forall, nullptr);
5715   return true;
5716 }
5717 void ConstructVisitor::Post(const parser::ForallStmt &) { PopScope(); }
5718 
5719 bool ConstructVisitor::Pre(const parser::BlockStmt &x) {
5720   CheckDef(x.v);
5721   PushScope(Scope::Kind::Block, nullptr);
5722   return false;
5723 }
5724 bool ConstructVisitor::Pre(const parser::EndBlockStmt &x) {
5725   PopScope();
5726   CheckRef(x.v);
5727   return false;
5728 }
5729 
5730 void ConstructVisitor::Post(const parser::Selector &x) {
5731   GetCurrentAssociation().selector = ResolveSelector(x);
5732 }
5733 
5734 void ConstructVisitor::Post(const parser::AssociateStmt &x) {
5735   CheckDef(x.t);
5736   PushScope(Scope::Kind::Block, nullptr);
5737   const auto assocCount{std::get<std::list<parser::Association>>(x.t).size()};
5738   for (auto nthLastAssoc{assocCount}; nthLastAssoc > 0; --nthLastAssoc) {
5739     SetCurrentAssociation(nthLastAssoc);
5740     if (auto *symbol{MakeAssocEntity()}) {
5741       if (ExtractCoarrayRef(GetCurrentAssociation().selector.expr)) { // C1103
5742         Say("Selector must not be a coindexed object"_err_en_US);
5743       }
5744       SetTypeFromAssociation(*symbol);
5745       SetAttrsFromAssociation(*symbol);
5746     }
5747   }
5748   PopAssociation(assocCount);
5749 }
5750 
5751 void ConstructVisitor::Post(const parser::EndAssociateStmt &x) {
5752   PopScope();
5753   CheckRef(x.v);
5754 }
5755 
5756 bool ConstructVisitor::Pre(const parser::Association &x) {
5757   PushAssociation();
5758   const auto &name{std::get<parser::Name>(x.t)};
5759   GetCurrentAssociation().name = &name;
5760   return true;
5761 }
5762 
5763 bool ConstructVisitor::Pre(const parser::ChangeTeamStmt &x) {
5764   CheckDef(x.t);
5765   PushScope(Scope::Kind::Block, nullptr);
5766   PushAssociation();
5767   return true;
5768 }
5769 
5770 void ConstructVisitor::Post(const parser::CoarrayAssociation &x) {
5771   const auto &decl{std::get<parser::CodimensionDecl>(x.t)};
5772   const auto &name{std::get<parser::Name>(decl.t)};
5773   if (auto *symbol{FindInScope(name)}) {
5774     const auto &selector{std::get<parser::Selector>(x.t)};
5775     if (auto sel{ResolveSelector(selector)}) {
5776       const Symbol *whole{UnwrapWholeSymbolDataRef(sel.expr)};
5777       if (!whole || whole->Corank() == 0) {
5778         Say(sel.source, // C1116
5779             "Selector in coarray association must name a coarray"_err_en_US);
5780       } else if (auto dynType{sel.expr->GetType()}) {
5781         if (!symbol->GetType()) {
5782           symbol->SetType(ToDeclTypeSpec(std::move(*dynType)));
5783         }
5784       }
5785     }
5786   }
5787 }
5788 
5789 void ConstructVisitor::Post(const parser::EndChangeTeamStmt &x) {
5790   PopAssociation();
5791   PopScope();
5792   CheckRef(x.t);
5793 }
5794 
5795 bool ConstructVisitor::Pre(const parser::SelectTypeConstruct &) {
5796   PushAssociation();
5797   return true;
5798 }
5799 
5800 void ConstructVisitor::Post(const parser::SelectTypeConstruct &) {
5801   PopAssociation();
5802 }
5803 
5804 void ConstructVisitor::Post(const parser::SelectTypeStmt &x) {
5805   auto &association{GetCurrentAssociation()};
5806   if (const std::optional<parser::Name> &name{std::get<1>(x.t)}) {
5807     // This isn't a name in the current scope, it is in each TypeGuardStmt
5808     MakePlaceholder(*name, MiscDetails::Kind::SelectTypeAssociateName);
5809     association.name = &*name;
5810     auto exprType{association.selector.expr->GetType()};
5811     if (ExtractCoarrayRef(association.selector.expr)) { // C1103
5812       Say("Selector must not be a coindexed object"_err_en_US);
5813     }
5814     if (exprType && !exprType->IsPolymorphic()) { // C1159
5815       Say(association.selector.source,
5816           "Selector '%s' in SELECT TYPE statement must be "
5817           "polymorphic"_err_en_US);
5818     }
5819   } else {
5820     if (const Symbol *
5821         whole{UnwrapWholeSymbolDataRef(association.selector.expr)}) {
5822       ConvertToObjectEntity(const_cast<Symbol &>(*whole));
5823       if (!IsVariableName(*whole)) {
5824         Say(association.selector.source, // C901
5825             "Selector is not a variable"_err_en_US);
5826         association = {};
5827       }
5828       if (const DeclTypeSpec * type{whole->GetType()}) {
5829         if (!type->IsPolymorphic()) { // C1159
5830           Say(association.selector.source,
5831               "Selector '%s' in SELECT TYPE statement must be "
5832               "polymorphic"_err_en_US);
5833         }
5834       }
5835     } else {
5836       Say(association.selector.source, // C1157
5837           "Selector is not a named variable: 'associate-name =>' is required"_err_en_US);
5838       association = {};
5839     }
5840   }
5841 }
5842 
5843 void ConstructVisitor::Post(const parser::SelectRankStmt &x) {
5844   auto &association{GetCurrentAssociation()};
5845   if (const std::optional<parser::Name> &name{std::get<1>(x.t)}) {
5846     // This isn't a name in the current scope, it is in each SelectRankCaseStmt
5847     MakePlaceholder(*name, MiscDetails::Kind::SelectRankAssociateName);
5848     association.name = &*name;
5849   }
5850 }
5851 
5852 bool ConstructVisitor::Pre(const parser::SelectTypeConstruct::TypeCase &) {
5853   PushScope(Scope::Kind::Block, nullptr);
5854   return true;
5855 }
5856 void ConstructVisitor::Post(const parser::SelectTypeConstruct::TypeCase &) {
5857   PopScope();
5858 }
5859 
5860 bool ConstructVisitor::Pre(const parser::SelectRankConstruct::RankCase &) {
5861   PushScope(Scope::Kind::Block, nullptr);
5862   return true;
5863 }
5864 void ConstructVisitor::Post(const parser::SelectRankConstruct::RankCase &) {
5865   PopScope();
5866 }
5867 
5868 void ConstructVisitor::Post(const parser::TypeGuardStmt::Guard &x) {
5869   if (auto *symbol{MakeAssocEntity()}) {
5870     if (std::holds_alternative<parser::Default>(x.u)) {
5871       SetTypeFromAssociation(*symbol);
5872     } else if (const auto *type{GetDeclTypeSpec()}) {
5873       symbol->SetType(*type);
5874     }
5875     SetAttrsFromAssociation(*symbol);
5876   }
5877 }
5878 
5879 void ConstructVisitor::Post(const parser::SelectRankCaseStmt::Rank &x) {
5880   if (auto *symbol{MakeAssocEntity()}) {
5881     SetTypeFromAssociation(*symbol);
5882     SetAttrsFromAssociation(*symbol);
5883     if (const auto *init{std::get_if<parser::ScalarIntConstantExpr>(&x.u)}) {
5884       if (auto val{EvaluateInt64(context(), *init)}) {
5885         auto &details{symbol->get<AssocEntityDetails>()};
5886         details.set_rank(*val);
5887       }
5888     }
5889   }
5890 }
5891 
5892 bool ConstructVisitor::Pre(const parser::SelectRankConstruct &) {
5893   PushAssociation();
5894   return true;
5895 }
5896 
5897 void ConstructVisitor::Post(const parser::SelectRankConstruct &) {
5898   PopAssociation();
5899 }
5900 
5901 bool ConstructVisitor::CheckDef(const std::optional<parser::Name> &x) {
5902   if (x) {
5903     MakeSymbol(*x, MiscDetails{MiscDetails::Kind::ConstructName});
5904   }
5905   return true;
5906 }
5907 
5908 void ConstructVisitor::CheckRef(const std::optional<parser::Name> &x) {
5909   if (x) {
5910     // Just add an occurrence of this name; checking is done in ValidateLabels
5911     FindSymbol(*x);
5912   }
5913 }
5914 
5915 // Make a symbol for the associating entity of the current association.
5916 Symbol *ConstructVisitor::MakeAssocEntity() {
5917   Symbol *symbol{nullptr};
5918   auto &association{GetCurrentAssociation()};
5919   if (association.name) {
5920     symbol = &MakeSymbol(*association.name, UnknownDetails{});
5921     if (symbol->has<AssocEntityDetails>() && symbol->owner() == currScope()) {
5922       Say(*association.name, // C1102
5923           "The associate name '%s' is already used in this associate statement"_err_en_US);
5924       return nullptr;
5925     }
5926   } else if (const Symbol *
5927       whole{UnwrapWholeSymbolDataRef(association.selector.expr)}) {
5928     symbol = &MakeSymbol(whole->name());
5929   } else {
5930     return nullptr;
5931   }
5932   if (auto &expr{association.selector.expr}) {
5933     symbol->set_details(AssocEntityDetails{common::Clone(*expr)});
5934   } else {
5935     symbol->set_details(AssocEntityDetails{});
5936   }
5937   return symbol;
5938 }
5939 
5940 // Set the type of symbol based on the current association selector.
5941 void ConstructVisitor::SetTypeFromAssociation(Symbol &symbol) {
5942   auto &details{symbol.get<AssocEntityDetails>()};
5943   const MaybeExpr *pexpr{&details.expr()};
5944   if (!*pexpr) {
5945     pexpr = &GetCurrentAssociation().selector.expr;
5946   }
5947   if (*pexpr) {
5948     const SomeExpr &expr{**pexpr};
5949     if (std::optional<evaluate::DynamicType> type{expr.GetType()}) {
5950       if (const auto *charExpr{
5951               evaluate::UnwrapExpr<evaluate::Expr<evaluate::SomeCharacter>>(
5952                   expr)}) {
5953         symbol.SetType(ToDeclTypeSpec(std::move(*type),
5954             FoldExpr(
5955                 std::visit([](const auto &kindChar) { return kindChar.LEN(); },
5956                     charExpr->u))));
5957       } else {
5958         symbol.SetType(ToDeclTypeSpec(std::move(*type)));
5959       }
5960     } else {
5961       // BOZ literals, procedure designators, &c. are not acceptable
5962       Say(symbol.name(), "Associate name '%s' must have a type"_err_en_US);
5963     }
5964   }
5965 }
5966 
5967 // If current selector is a variable, set some of its attributes on symbol.
5968 void ConstructVisitor::SetAttrsFromAssociation(Symbol &symbol) {
5969   Attrs attrs{evaluate::GetAttrs(GetCurrentAssociation().selector.expr)};
5970   symbol.attrs() |= attrs &
5971       Attrs{Attr::TARGET, Attr::ASYNCHRONOUS, Attr::VOLATILE, Attr::CONTIGUOUS};
5972   if (attrs.test(Attr::POINTER)) {
5973     symbol.attrs().set(Attr::TARGET);
5974   }
5975 }
5976 
5977 ConstructVisitor::Selector ConstructVisitor::ResolveSelector(
5978     const parser::Selector &x) {
5979   return std::visit(common::visitors{
5980                         [&](const parser::Expr &expr) {
5981                           return Selector{expr.source, EvaluateExpr(x)};
5982                         },
5983                         [&](const parser::Variable &var) {
5984                           return Selector{var.GetSource(), EvaluateExpr(x)};
5985                         },
5986                     },
5987       x.u);
5988 }
5989 
5990 // Set the current association to the nth to the last association on the
5991 // association stack.  The top of the stack is at n = 1.  This allows access
5992 // to the interior of a list of associations at the top of the stack.
5993 void ConstructVisitor::SetCurrentAssociation(std::size_t n) {
5994   CHECK(n > 0 && n <= associationStack_.size());
5995   currentAssociation_ = &associationStack_[associationStack_.size() - n];
5996 }
5997 
5998 ConstructVisitor::Association &ConstructVisitor::GetCurrentAssociation() {
5999   CHECK(currentAssociation_);
6000   return *currentAssociation_;
6001 }
6002 
6003 void ConstructVisitor::PushAssociation() {
6004   associationStack_.emplace_back(Association{});
6005   currentAssociation_ = &associationStack_.back();
6006 }
6007 
6008 void ConstructVisitor::PopAssociation(std::size_t count) {
6009   CHECK(count > 0 && count <= associationStack_.size());
6010   associationStack_.resize(associationStack_.size() - count);
6011   currentAssociation_ =
6012       associationStack_.empty() ? nullptr : &associationStack_.back();
6013 }
6014 
6015 const DeclTypeSpec &ConstructVisitor::ToDeclTypeSpec(
6016     evaluate::DynamicType &&type) {
6017   switch (type.category()) {
6018     SWITCH_COVERS_ALL_CASES
6019   case common::TypeCategory::Integer:
6020   case common::TypeCategory::Real:
6021   case common::TypeCategory::Complex:
6022     return context().MakeNumericType(type.category(), type.kind());
6023   case common::TypeCategory::Logical:
6024     return context().MakeLogicalType(type.kind());
6025   case common::TypeCategory::Derived:
6026     if (type.IsAssumedType()) {
6027       return currScope().MakeTypeStarType();
6028     } else if (type.IsUnlimitedPolymorphic()) {
6029       return currScope().MakeClassStarType();
6030     } else {
6031       return currScope().MakeDerivedType(
6032           type.IsPolymorphic() ? DeclTypeSpec::ClassDerived
6033                                : DeclTypeSpec::TypeDerived,
6034           common::Clone(type.GetDerivedTypeSpec())
6035 
6036       );
6037     }
6038   case common::TypeCategory::Character:
6039     CRASH_NO_CASE;
6040   }
6041 }
6042 
6043 const DeclTypeSpec &ConstructVisitor::ToDeclTypeSpec(
6044     evaluate::DynamicType &&type, MaybeSubscriptIntExpr &&length) {
6045   CHECK(type.category() == common::TypeCategory::Character);
6046   if (length) {
6047     return currScope().MakeCharacterType(
6048         ParamValue{SomeIntExpr{*std::move(length)}, common::TypeParamAttr::Len},
6049         KindExpr{type.kind()});
6050   } else {
6051     return currScope().MakeCharacterType(
6052         ParamValue::Deferred(common::TypeParamAttr::Len),
6053         KindExpr{type.kind()});
6054   }
6055 }
6056 
6057 // ResolveNamesVisitor implementation
6058 
6059 bool ResolveNamesVisitor::Pre(const parser::FunctionReference &x) {
6060   HandleCall(Symbol::Flag::Function, x.v);
6061   return false;
6062 }
6063 bool ResolveNamesVisitor::Pre(const parser::CallStmt &x) {
6064   HandleCall(Symbol::Flag::Subroutine, x.v);
6065   return false;
6066 }
6067 
6068 bool ResolveNamesVisitor::Pre(const parser::ImportStmt &x) {
6069   auto &scope{currScope()};
6070   // Check C896 and C899: where IMPORT statements are allowed
6071   switch (scope.kind()) {
6072   case Scope::Kind::Module:
6073     if (scope.IsModule()) {
6074       Say("IMPORT is not allowed in a module scoping unit"_err_en_US);
6075       return false;
6076     } else if (x.kind == common::ImportKind::None) {
6077       Say("IMPORT,NONE is not allowed in a submodule scoping unit"_err_en_US);
6078       return false;
6079     }
6080     break;
6081   case Scope::Kind::MainProgram:
6082     Say("IMPORT is not allowed in a main program scoping unit"_err_en_US);
6083     return false;
6084   case Scope::Kind::Subprogram:
6085     if (scope.parent().IsGlobal()) {
6086       Say("IMPORT is not allowed in an external subprogram scoping unit"_err_en_US);
6087       return false;
6088     }
6089     break;
6090   case Scope::Kind::BlockData: // C1415 (in part)
6091     Say("IMPORT is not allowed in a BLOCK DATA subprogram"_err_en_US);
6092     return false;
6093   default:;
6094   }
6095   if (auto error{scope.SetImportKind(x.kind)}) {
6096     Say(std::move(*error));
6097   }
6098   for (auto &name : x.names) {
6099     if (FindSymbol(scope.parent(), name)) {
6100       scope.add_importName(name.source);
6101     } else {
6102       Say(name, "'%s' not found in host scope"_err_en_US);
6103     }
6104   }
6105   prevImportStmt_ = currStmtSource();
6106   return false;
6107 }
6108 
6109 const parser::Name *DeclarationVisitor::ResolveStructureComponent(
6110     const parser::StructureComponent &x) {
6111   return FindComponent(ResolveDataRef(x.base), x.component);
6112 }
6113 
6114 const parser::Name *DeclarationVisitor::ResolveDesignator(
6115     const parser::Designator &x) {
6116   return std::visit(
6117       common::visitors{
6118           [&](const parser::DataRef &x) { return ResolveDataRef(x); },
6119           [&](const parser::Substring &x) {
6120             return ResolveDataRef(std::get<parser::DataRef>(x.t));
6121           },
6122       },
6123       x.u);
6124 }
6125 
6126 const parser::Name *DeclarationVisitor::ResolveDataRef(
6127     const parser::DataRef &x) {
6128   return std::visit(
6129       common::visitors{
6130           [=](const parser::Name &y) { return ResolveName(y); },
6131           [=](const Indirection<parser::StructureComponent> &y) {
6132             return ResolveStructureComponent(y.value());
6133           },
6134           [&](const Indirection<parser::ArrayElement> &y) {
6135             Walk(y.value().subscripts);
6136             const parser::Name *name{ResolveDataRef(y.value().base)};
6137             if (name && name->symbol) {
6138               if (!IsProcedure(*name->symbol)) {
6139                 ConvertToObjectEntity(*name->symbol);
6140               } else if (!context().HasError(*name->symbol)) {
6141                 SayWithDecl(*name, *name->symbol,
6142                     "Cannot reference function '%s' as data"_err_en_US);
6143               }
6144             }
6145             return name;
6146           },
6147           [&](const Indirection<parser::CoindexedNamedObject> &y) {
6148             Walk(y.value().imageSelector);
6149             return ResolveDataRef(y.value().base);
6150           },
6151       },
6152       x.u);
6153 }
6154 
6155 // If implicit types are allowed, ensure name is in the symbol table.
6156 // Otherwise, report an error if it hasn't been declared.
6157 const parser::Name *DeclarationVisitor::ResolveName(const parser::Name &name) {
6158   FindSymbol(name);
6159   if (CheckForHostAssociatedImplicit(name)) {
6160     NotePossibleBadForwardRef(name);
6161     return &name;
6162   }
6163   if (Symbol * symbol{name.symbol}) {
6164     if (CheckUseError(name)) {
6165       return nullptr; // reported an error
6166     }
6167     NotePossibleBadForwardRef(name);
6168     symbol->set(Symbol::Flag::ImplicitOrError, false);
6169     if (IsUplevelReference(*symbol)) {
6170       MakeHostAssocSymbol(name, *symbol);
6171     } else if (IsDummy(*symbol) ||
6172         (!symbol->GetType() && FindCommonBlockContaining(*symbol))) {
6173       ConvertToObjectEntity(*symbol);
6174       ApplyImplicitRules(*symbol);
6175     }
6176     if (checkIndexUseInOwnBounds_ &&
6177         *checkIndexUseInOwnBounds_ == name.source) {
6178       Say(name,
6179           "Implied DO index '%s' uses an object of the same name in its bounds expressions"_port_en_US,
6180           name.source);
6181     }
6182     return &name;
6183   }
6184   if (isImplicitNoneType()) {
6185     Say(name, "No explicit type declared for '%s'"_err_en_US);
6186     return nullptr;
6187   }
6188   // Create the symbol then ensure it is accessible
6189   if (checkIndexUseInOwnBounds_ && *checkIndexUseInOwnBounds_ == name.source) {
6190     Say(name,
6191         "Implied DO index '%s' uses itself in its own bounds expressions"_err_en_US,
6192         name.source);
6193   }
6194   MakeSymbol(InclusiveScope(), name.source, Attrs{});
6195   auto *symbol{FindSymbol(name)};
6196   if (!symbol) {
6197     Say(name,
6198         "'%s' from host scoping unit is not accessible due to IMPORT"_err_en_US);
6199     return nullptr;
6200   }
6201   ConvertToObjectEntity(*symbol);
6202   ApplyImplicitRules(*symbol);
6203   NotePossibleBadForwardRef(name);
6204   return &name;
6205 }
6206 
6207 // A specification expression may refer to a symbol in the host procedure that
6208 // is implicitly typed. Because specification parts are processed before
6209 // execution parts, this may be the first time we see the symbol. It can't be a
6210 // local in the current scope (because it's in a specification expression) so
6211 // either it is implicitly declared in the host procedure or it is an error.
6212 // We create a symbol in the host assuming it is the former; if that proves to
6213 // be wrong we report an error later in CheckDeclarations().
6214 bool DeclarationVisitor::CheckForHostAssociatedImplicit(
6215     const parser::Name &name) {
6216   if (inExecutionPart_) {
6217     return false;
6218   }
6219   if (name.symbol) {
6220     ApplyImplicitRules(*name.symbol, true);
6221   }
6222   Symbol *hostSymbol;
6223   Scope *host{GetHostProcedure()};
6224   if (!host || isImplicitNoneType(*host)) {
6225     return false;
6226   }
6227   if (!name.symbol) {
6228     hostSymbol = &MakeSymbol(*host, name.source, Attrs{});
6229     ConvertToObjectEntity(*hostSymbol);
6230     ApplyImplicitRules(*hostSymbol);
6231     hostSymbol->set(Symbol::Flag::ImplicitOrError);
6232   } else if (name.symbol->test(Symbol::Flag::ImplicitOrError)) {
6233     hostSymbol = name.symbol;
6234   } else {
6235     return false;
6236   }
6237   Symbol &symbol{MakeHostAssocSymbol(name, *hostSymbol)};
6238   if (isImplicitNoneType()) {
6239     symbol.get<HostAssocDetails>().implicitOrExplicitTypeError = true;
6240   } else {
6241     symbol.get<HostAssocDetails>().implicitOrSpecExprError = true;
6242   }
6243   return true;
6244 }
6245 
6246 bool DeclarationVisitor::IsUplevelReference(const Symbol &symbol) {
6247   const Scope &symbolUnit{GetProgramUnitContaining(symbol)};
6248   if (symbolUnit == GetProgramUnitContaining(currScope())) {
6249     return false;
6250   } else {
6251     Scope::Kind kind{symbolUnit.kind()};
6252     return kind == Scope::Kind::Subprogram || kind == Scope::Kind::MainProgram;
6253   }
6254 }
6255 
6256 // base is a part-ref of a derived type; find the named component in its type.
6257 // Also handles intrinsic type parameter inquiries (%kind, %len) and
6258 // COMPLEX component references (%re, %im).
6259 const parser::Name *DeclarationVisitor::FindComponent(
6260     const parser::Name *base, const parser::Name &component) {
6261   if (!base || !base->symbol) {
6262     return nullptr;
6263   }
6264   auto &symbol{base->symbol->GetUltimate()};
6265   if (!symbol.has<AssocEntityDetails>() && !ConvertToObjectEntity(symbol)) {
6266     SayWithDecl(*base, symbol,
6267         "'%s' is an invalid base for a component reference"_err_en_US);
6268     return nullptr;
6269   }
6270   auto *type{symbol.GetType()};
6271   if (!type) {
6272     return nullptr; // should have already reported error
6273   }
6274   if (const IntrinsicTypeSpec * intrinsic{type->AsIntrinsic()}) {
6275     auto name{component.ToString()};
6276     auto category{intrinsic->category()};
6277     MiscDetails::Kind miscKind{MiscDetails::Kind::None};
6278     if (name == "kind") {
6279       miscKind = MiscDetails::Kind::KindParamInquiry;
6280     } else if (category == TypeCategory::Character) {
6281       if (name == "len") {
6282         miscKind = MiscDetails::Kind::LenParamInquiry;
6283       }
6284     } else if (category == TypeCategory::Complex) {
6285       if (name == "re") {
6286         miscKind = MiscDetails::Kind::ComplexPartRe;
6287       } else if (name == "im") {
6288         miscKind = MiscDetails::Kind::ComplexPartIm;
6289       }
6290     }
6291     if (miscKind != MiscDetails::Kind::None) {
6292       MakePlaceholder(component, miscKind);
6293       return nullptr;
6294     }
6295   } else if (const DerivedTypeSpec * derived{type->AsDerived()}) {
6296     if (const Scope * scope{derived->scope()}) {
6297       if (Resolve(component, scope->FindComponent(component.source))) {
6298         if (auto msg{
6299                 CheckAccessibleComponent(currScope(), *component.symbol)}) {
6300           context().Say(component.source, *msg);
6301         }
6302         return &component;
6303       } else {
6304         SayDerivedType(component.source,
6305             "Component '%s' not found in derived type '%s'"_err_en_US, *scope);
6306       }
6307     }
6308     return nullptr;
6309   }
6310   if (symbol.test(Symbol::Flag::Implicit)) {
6311     Say(*base,
6312         "'%s' is not an object of derived type; it is implicitly typed"_err_en_US);
6313   } else {
6314     SayWithDecl(
6315         *base, symbol, "'%s' is not an object of derived type"_err_en_US);
6316   }
6317   return nullptr;
6318 }
6319 
6320 void DeclarationVisitor::Initialization(const parser::Name &name,
6321     const parser::Initialization &init, bool inComponentDecl) {
6322   // Traversal of the initializer was deferred to here so that the
6323   // symbol being declared can be available for use in the expression, e.g.:
6324   //   real, parameter :: x = tiny(x)
6325   if (!name.symbol) {
6326     return;
6327   }
6328   Symbol &ultimate{name.symbol->GetUltimate()};
6329   if (IsAllocatable(ultimate)) {
6330     Say(name, "Allocatable object '%s' cannot be initialized"_err_en_US);
6331     return;
6332   }
6333   if (auto *object{ultimate.detailsIf<ObjectEntityDetails>()}) {
6334     // TODO: check C762 - all bounds and type parameters of component
6335     // are colons or constant expressions if component is initialized
6336     std::visit(
6337         common::visitors{
6338             [&](const parser::ConstantExpr &expr) {
6339               NonPointerInitialization(name, expr);
6340             },
6341             [&](const parser::NullInit &null) {
6342               Walk(null);
6343               if (auto nullInit{EvaluateExpr(null)}) {
6344                 if (!evaluate::IsNullPointer(*nullInit)) {
6345                   Say(name,
6346                       "Pointer initializer must be intrinsic NULL()"_err_en_US); // C813
6347                 } else if (IsPointer(ultimate)) {
6348                   object->set_init(std::move(*nullInit));
6349                 } else {
6350                   Say(name,
6351                       "Non-pointer component '%s' initialized with null pointer"_err_en_US);
6352                 }
6353               }
6354             },
6355             [&](const parser::InitialDataTarget &) {
6356               // Defer analysis to the end of the specification part
6357               // so that forward references and attribute checks like SAVE
6358               // work better.
6359               ultimate.set(Symbol::Flag::InDataStmt);
6360             },
6361             [&](const std::list<Indirection<parser::DataStmtValue>> &) {
6362               // Handled later in data-to-inits conversion
6363               ultimate.set(Symbol::Flag::InDataStmt);
6364             },
6365         },
6366         init.u);
6367   }
6368 }
6369 
6370 void DeclarationVisitor::PointerInitialization(
6371     const parser::Name &name, const parser::InitialDataTarget &target) {
6372   if (name.symbol) {
6373     Symbol &ultimate{name.symbol->GetUltimate()};
6374     if (!context().HasError(ultimate)) {
6375       if (IsPointer(ultimate)) {
6376         if (auto *details{ultimate.detailsIf<ObjectEntityDetails>()}) {
6377           CHECK(!details->init());
6378           Walk(target);
6379           if (MaybeExpr expr{EvaluateExpr(target)}) {
6380             // Validation is done in declaration checking.
6381             details->set_init(std::move(*expr));
6382           }
6383         }
6384       } else {
6385         Say(name,
6386             "'%s' is not a pointer but is initialized like one"_err_en_US);
6387         context().SetError(ultimate);
6388       }
6389     }
6390   }
6391 }
6392 void DeclarationVisitor::PointerInitialization(
6393     const parser::Name &name, const parser::ProcPointerInit &target) {
6394   if (name.symbol) {
6395     Symbol &ultimate{name.symbol->GetUltimate()};
6396     if (!context().HasError(ultimate)) {
6397       if (IsProcedurePointer(ultimate)) {
6398         auto &details{ultimate.get<ProcEntityDetails>()};
6399         CHECK(!details.init());
6400         Walk(target);
6401         if (const auto *targetName{std::get_if<parser::Name>(&target.u)}) {
6402           if (targetName->symbol) {
6403             // Validation is done in declaration checking.
6404             details.set_init(*targetName->symbol);
6405           }
6406         } else {
6407           details.set_init(nullptr); // explicit NULL()
6408         }
6409       } else {
6410         Say(name,
6411             "'%s' is not a procedure pointer but is initialized "
6412             "like one"_err_en_US);
6413         context().SetError(ultimate);
6414       }
6415     }
6416   }
6417 }
6418 
6419 void DeclarationVisitor::NonPointerInitialization(
6420     const parser::Name &name, const parser::ConstantExpr &expr) {
6421   if (name.symbol) {
6422     Symbol &ultimate{name.symbol->GetUltimate()};
6423     if (!context().HasError(ultimate) && !context().HasError(name.symbol)) {
6424       if (IsPointer(ultimate)) {
6425         Say(name,
6426             "'%s' is a pointer but is not initialized like one"_err_en_US);
6427       } else if (auto *details{ultimate.detailsIf<ObjectEntityDetails>()}) {
6428         CHECK(!details->init());
6429         Walk(expr);
6430         if (ultimate.owner().IsParameterizedDerivedType()) {
6431           // Can't convert to type of component, which might not yet
6432           // be known; that's done later during PDT instantiation.
6433           if (MaybeExpr value{EvaluateExpr(expr)}) {
6434             details->set_init(std::move(*value));
6435           }
6436         } else if (MaybeExpr folded{EvaluateNonPointerInitializer(
6437                        ultimate, expr, expr.thing.value().source)}) {
6438           details->set_init(std::move(*folded));
6439         }
6440       }
6441     }
6442   }
6443 }
6444 
6445 void ResolveNamesVisitor::HandleCall(
6446     Symbol::Flag procFlag, const parser::Call &call) {
6447   std::visit(
6448       common::visitors{
6449           [&](const parser::Name &x) { HandleProcedureName(procFlag, x); },
6450           [&](const parser::ProcComponentRef &x) { Walk(x); },
6451       },
6452       std::get<parser::ProcedureDesignator>(call.t).u);
6453   Walk(std::get<std::list<parser::ActualArgSpec>>(call.t));
6454 }
6455 
6456 void ResolveNamesVisitor::HandleProcedureName(
6457     Symbol::Flag flag, const parser::Name &name) {
6458   CHECK(flag == Symbol::Flag::Function || flag == Symbol::Flag::Subroutine);
6459   auto *symbol{FindSymbol(NonDerivedTypeScope(), name)};
6460   if (!symbol) {
6461     if (IsIntrinsic(name.source, flag)) {
6462       symbol =
6463           &MakeSymbol(InclusiveScope(), name.source, Attrs{Attr::INTRINSIC});
6464     } else {
6465       symbol = &MakeSymbol(context().globalScope(), name.source, Attrs{});
6466     }
6467     Resolve(name, *symbol);
6468     if (!symbol->attrs().test(Attr::INTRINSIC)) {
6469       if (CheckImplicitNoneExternal(name.source, *symbol)) {
6470         MakeExternal(*symbol);
6471       }
6472     }
6473     ConvertToProcEntity(*symbol);
6474     SetProcFlag(name, *symbol, flag);
6475   } else if (CheckUseError(name)) {
6476     // error was reported
6477   } else {
6478     auto &nonUltimateSymbol = *symbol;
6479     symbol = &Resolve(name, symbol)->GetUltimate();
6480     bool convertedToProcEntity{ConvertToProcEntity(*symbol)};
6481     if (convertedToProcEntity && !symbol->attrs().test(Attr::EXTERNAL) &&
6482         IsIntrinsic(symbol->name(), flag) && !IsDummy(*symbol)) {
6483       AcquireIntrinsicProcedureFlags(*symbol);
6484     }
6485     if (!SetProcFlag(name, *symbol, flag)) {
6486       return; // reported error
6487     }
6488     CheckImplicitNoneExternal(name.source, *symbol);
6489     if (symbol->has<SubprogramDetails>() &&
6490         symbol->attrs().test(Attr::ABSTRACT)) {
6491       Say(name, "Abstract interface '%s' may not be called"_err_en_US);
6492     } else if (IsProcedure(*symbol) || symbol->has<DerivedTypeDetails>() ||
6493         symbol->has<AssocEntityDetails>()) {
6494       // Symbols with DerivedTypeDetails and AssocEntityDetails are accepted
6495       // here as procedure-designators because this means the related
6496       // FunctionReference are mis-parsed structure constructors or array
6497       // references that will be fixed later when analyzing expressions.
6498     } else if (symbol->has<ObjectEntityDetails>()) {
6499       // Symbols with ObjectEntityDetails are also accepted because this can be
6500       // a mis-parsed array references that will be fixed later. Ensure that if
6501       // this is a symbol from a host procedure, a symbol with HostAssocDetails
6502       // is created for the current scope.
6503       // Operate on non ultimate symbol so that HostAssocDetails are also
6504       // created for symbols used associated in the host procedure.
6505       if (IsUplevelReference(nonUltimateSymbol)) {
6506         MakeHostAssocSymbol(name, nonUltimateSymbol);
6507       }
6508     } else if (symbol->test(Symbol::Flag::Implicit)) {
6509       Say(name,
6510           "Use of '%s' as a procedure conflicts with its implicit definition"_err_en_US);
6511     } else {
6512       SayWithDecl(name, *symbol,
6513           "Use of '%s' as a procedure conflicts with its declaration"_err_en_US);
6514     }
6515   }
6516 }
6517 
6518 bool ResolveNamesVisitor::CheckImplicitNoneExternal(
6519     const SourceName &name, const Symbol &symbol) {
6520   if (isImplicitNoneExternal() && !symbol.attrs().test(Attr::EXTERNAL) &&
6521       !symbol.attrs().test(Attr::INTRINSIC) && !symbol.HasExplicitInterface()) {
6522     Say(name,
6523         "'%s' is an external procedure without the EXTERNAL"
6524         " attribute in a scope with IMPLICIT NONE(EXTERNAL)"_err_en_US);
6525     return false;
6526   }
6527   return true;
6528 }
6529 
6530 // Variant of HandleProcedureName() for use while skimming the executable
6531 // part of a subprogram to catch calls to dummy procedures that are part
6532 // of the subprogram's interface, and to mark as procedures any symbols
6533 // that might otherwise have been miscategorized as objects.
6534 void ResolveNamesVisitor::NoteExecutablePartCall(
6535     Symbol::Flag flag, const parser::Call &call) {
6536   auto &designator{std::get<parser::ProcedureDesignator>(call.t)};
6537   if (const auto *name{std::get_if<parser::Name>(&designator.u)}) {
6538     // Subtlety: The symbol pointers in the parse tree are not set, because
6539     // they might end up resolving elsewhere (e.g., construct entities in
6540     // SELECT TYPE).
6541     if (Symbol * symbol{currScope().FindSymbol(name->source)}) {
6542       Symbol::Flag other{flag == Symbol::Flag::Subroutine
6543               ? Symbol::Flag::Function
6544               : Symbol::Flag::Subroutine};
6545       if (!symbol->test(other)) {
6546         ConvertToProcEntity(*symbol);
6547         if (symbol->has<ProcEntityDetails>()) {
6548           symbol->set(flag);
6549           if (IsDummy(*symbol)) {
6550             symbol->attrs().set(Attr::EXTERNAL);
6551           }
6552           ApplyImplicitRules(*symbol);
6553         }
6554       }
6555     }
6556   }
6557 }
6558 
6559 static bool IsLocallyImplicitGlobalSymbol(
6560     const Symbol &symbol, const parser::Name &localName) {
6561   return symbol.owner().IsGlobal() &&
6562       (!symbol.scope() ||
6563           !symbol.scope()->sourceRange().Contains(localName.source));
6564 }
6565 
6566 static bool TypesMismatchIfNonNull(
6567     const DeclTypeSpec *type1, const DeclTypeSpec *type2) {
6568   return type1 && type2 && *type1 != *type2;
6569 }
6570 
6571 // Check and set the Function or Subroutine flag on symbol; false on error.
6572 bool ResolveNamesVisitor::SetProcFlag(
6573     const parser::Name &name, Symbol &symbol, Symbol::Flag flag) {
6574   if (symbol.test(Symbol::Flag::Function) && flag == Symbol::Flag::Subroutine) {
6575     SayWithDecl(
6576         name, symbol, "Cannot call function '%s' like a subroutine"_err_en_US);
6577     return false;
6578   } else if (symbol.test(Symbol::Flag::Subroutine) &&
6579       flag == Symbol::Flag::Function) {
6580     SayWithDecl(
6581         name, symbol, "Cannot call subroutine '%s' like a function"_err_en_US);
6582     return false;
6583   } else if (flag == Symbol::Flag::Function &&
6584       IsLocallyImplicitGlobalSymbol(symbol, name) &&
6585       TypesMismatchIfNonNull(symbol.GetType(), GetImplicitType(symbol))) {
6586     SayWithDecl(name, symbol,
6587         "Implicit declaration of function '%s' has a different result type than in previous declaration"_err_en_US);
6588     return false;
6589   } else if (symbol.has<ProcEntityDetails>()) {
6590     symbol.set(flag); // in case it hasn't been set yet
6591     if (flag == Symbol::Flag::Function) {
6592       ApplyImplicitRules(symbol);
6593     }
6594     if (symbol.attrs().test(Attr::INTRINSIC)) {
6595       AcquireIntrinsicProcedureFlags(symbol);
6596     }
6597   } else if (symbol.GetType() && flag == Symbol::Flag::Subroutine) {
6598     SayWithDecl(
6599         name, symbol, "Cannot call function '%s' like a subroutine"_err_en_US);
6600   } else if (symbol.attrs().test(Attr::INTRINSIC)) {
6601     AcquireIntrinsicProcedureFlags(symbol);
6602   }
6603   return true;
6604 }
6605 
6606 bool ModuleVisitor::Pre(const parser::AccessStmt &x) {
6607   Attr accessAttr{AccessSpecToAttr(std::get<parser::AccessSpec>(x.t))};
6608   if (!currScope().IsModule()) { // C869
6609     Say(currStmtSource().value(),
6610         "%s statement may only appear in the specification part of a module"_err_en_US,
6611         EnumToString(accessAttr));
6612     return false;
6613   }
6614   const auto &accessIds{std::get<std::list<parser::AccessId>>(x.t)};
6615   if (accessIds.empty()) {
6616     if (prevAccessStmt_) { // C869
6617       Say("The default accessibility of this module has already been declared"_err_en_US)
6618           .Attach(*prevAccessStmt_, "Previous declaration"_en_US);
6619     }
6620     prevAccessStmt_ = currStmtSource();
6621     defaultAccess_ = accessAttr;
6622   } else {
6623     for (const auto &accessId : accessIds) {
6624       std::visit(
6625           common::visitors{
6626               [=](const parser::Name &y) {
6627                 Resolve(y, SetAccess(y.source, accessAttr));
6628               },
6629               [=](const Indirection<parser::GenericSpec> &y) {
6630                 auto info{GenericSpecInfo{y.value()}};
6631                 const auto &symbolName{info.symbolName()};
6632                 if (auto *symbol{FindInScope(symbolName)}) {
6633                   info.Resolve(&SetAccess(symbolName, accessAttr, symbol));
6634                 } else if (info.kind().IsName()) {
6635                   info.Resolve(&SetAccess(symbolName, accessAttr));
6636                 } else {
6637                   Say(symbolName, "Generic spec '%s' not found"_err_en_US);
6638                 }
6639               },
6640           },
6641           accessId.u);
6642     }
6643   }
6644   return false;
6645 }
6646 
6647 // Set the access specification for this symbol.
6648 Symbol &ModuleVisitor::SetAccess(
6649     const SourceName &name, Attr attr, Symbol *symbol) {
6650   if (!symbol) {
6651     symbol = &MakeSymbol(name);
6652   }
6653   Attrs &attrs{symbol->attrs()};
6654   if (attrs.HasAny({Attr::PUBLIC, Attr::PRIVATE})) {
6655     // PUBLIC/PRIVATE already set: make it a fatal error if it changed
6656     Attr prev = attrs.test(Attr::PUBLIC) ? Attr::PUBLIC : Attr::PRIVATE;
6657     Say(name,
6658         WithSeverity(
6659             "The accessibility of '%s' has already been specified as %s"_warn_en_US,
6660             attr != prev ? parser::Severity::Error : parser::Severity::Warning),
6661         MakeOpName(name), EnumToString(prev));
6662   } else {
6663     attrs.set(attr);
6664   }
6665   return *symbol;
6666 }
6667 
6668 static bool NeedsExplicitType(const Symbol &symbol) {
6669   if (symbol.has<UnknownDetails>()) {
6670     return true;
6671   } else if (const auto *details{symbol.detailsIf<EntityDetails>()}) {
6672     return !details->type();
6673   } else if (const auto *details{symbol.detailsIf<ObjectEntityDetails>()}) {
6674     return !details->type();
6675   } else if (const auto *details{symbol.detailsIf<ProcEntityDetails>()}) {
6676     return !details->interface().symbol() && !details->interface().type();
6677   } else {
6678     return false;
6679   }
6680 }
6681 
6682 bool ResolveNamesVisitor::Pre(const parser::SpecificationPart &x) {
6683   const auto &[accDecls, ompDecls, compilerDirectives, useStmts, importStmts,
6684       implicitPart, decls] = x.t;
6685   auto flagRestorer{common::ScopedSet(inSpecificationPart_, true)};
6686   auto stateRestorer{
6687       common::ScopedSet(specPartState_, SpecificationPartState{})};
6688   Walk(accDecls);
6689   Walk(ompDecls);
6690   Walk(compilerDirectives);
6691   Walk(useStmts);
6692   ClearUseRenames();
6693   ClearUseOnly();
6694   ClearExplicitIntrinsicUses();
6695   Walk(importStmts);
6696   Walk(implicitPart);
6697   for (const auto &decl : decls) {
6698     if (const auto *spec{
6699             std::get_if<parser::SpecificationConstruct>(&decl.u)}) {
6700       PreSpecificationConstruct(*spec);
6701     }
6702   }
6703   Walk(decls);
6704   FinishSpecificationPart(decls);
6705   return false;
6706 }
6707 
6708 // Initial processing on specification constructs, before visiting them.
6709 void ResolveNamesVisitor::PreSpecificationConstruct(
6710     const parser::SpecificationConstruct &spec) {
6711   std::visit(
6712       common::visitors{
6713           [&](const parser::Statement<Indirection<parser::GenericStmt>> &y) {
6714             CreateGeneric(std::get<parser::GenericSpec>(y.statement.value().t));
6715           },
6716           [&](const Indirection<parser::InterfaceBlock> &y) {
6717             const auto &stmt{std::get<parser::Statement<parser::InterfaceStmt>>(
6718                 y.value().t)};
6719             if (const auto *spec{parser::Unwrap<parser::GenericSpec>(stmt)}) {
6720               CreateGeneric(*spec);
6721             }
6722           },
6723           [&](const parser::Statement<parser::OtherSpecificationStmt> &y) {
6724             if (const auto *commonStmt{parser::Unwrap<parser::CommonStmt>(y)}) {
6725               CreateCommonBlockSymbols(*commonStmt);
6726             }
6727           },
6728           [&](const auto &) {},
6729       },
6730       spec.u);
6731 }
6732 
6733 void ResolveNamesVisitor::CreateCommonBlockSymbols(
6734     const parser::CommonStmt &commonStmt) {
6735   for (const parser::CommonStmt::Block &block : commonStmt.blocks) {
6736     const auto &[name, objects] = block.t;
6737     Symbol &commonBlock{MakeCommonBlockSymbol(name)};
6738     for (const auto &object : objects) {
6739       Symbol &obj{DeclareObjectEntity(std::get<parser::Name>(object.t))};
6740       if (auto *details{obj.detailsIf<ObjectEntityDetails>()}) {
6741         details->set_commonBlock(commonBlock);
6742         commonBlock.get<CommonBlockDetails>().add_object(obj);
6743       }
6744     }
6745   }
6746 }
6747 
6748 void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) {
6749   auto info{GenericSpecInfo{x}};
6750   const SourceName &symbolName{info.symbolName()};
6751   if (IsLogicalConstant(context(), symbolName)) {
6752     Say(symbolName,
6753         "Logical constant '%s' may not be used as a defined operator"_err_en_US);
6754     return;
6755   }
6756   GenericDetails genericDetails;
6757   if (Symbol * existing{FindInScope(symbolName)}) {
6758     if (existing->has<GenericDetails>()) {
6759       info.Resolve(existing);
6760       return; // already have generic, add to it
6761     }
6762     Symbol &ultimate{existing->GetUltimate()};
6763     if (auto *ultimateDetails{ultimate.detailsIf<GenericDetails>()}) {
6764       // convert a use-associated generic into a local generic
6765       genericDetails.CopyFrom(*ultimateDetails);
6766       AddGenericUse(genericDetails, existing->name(),
6767           existing->get<UseDetails>().symbol());
6768     } else if (ultimate.has<SubprogramDetails>() ||
6769         ultimate.has<SubprogramNameDetails>()) {
6770       genericDetails.set_specific(ultimate);
6771     } else if (ultimate.has<DerivedTypeDetails>()) {
6772       genericDetails.set_derivedType(ultimate);
6773     } else {
6774       SayAlreadyDeclared(symbolName, *existing);
6775     }
6776     EraseSymbol(*existing);
6777   }
6778   info.Resolve(&MakeSymbol(symbolName, Attrs{}, std::move(genericDetails)));
6779 }
6780 
6781 void ResolveNamesVisitor::FinishSpecificationPart(
6782     const std::list<parser::DeclarationConstruct> &decls) {
6783   badStmtFuncFound_ = false;
6784   FinishFunctionResult();
6785   CheckImports();
6786   bool inModule{currScope().kind() == Scope::Kind::Module};
6787   for (auto &pair : currScope()) {
6788     auto &symbol{*pair.second};
6789     if (NeedsExplicitType(symbol)) {
6790       ApplyImplicitRules(symbol);
6791     }
6792     if (IsDummy(symbol) && isImplicitNoneType() &&
6793         symbol.test(Symbol::Flag::Implicit) && !context().HasError(symbol)) {
6794       Say(symbol.name(),
6795           "No explicit type declared for dummy argument '%s'"_err_en_US);
6796       context().SetError(symbol);
6797     }
6798     if (symbol.has<GenericDetails>()) {
6799       CheckGenericProcedures(symbol);
6800     }
6801     if (inModule && symbol.attrs().test(Attr::EXTERNAL) &&
6802         !symbol.test(Symbol::Flag::Function) &&
6803         !symbol.test(Symbol::Flag::Subroutine)) {
6804       // in a module, external proc without return type is subroutine
6805       symbol.set(
6806           symbol.GetType() ? Symbol::Flag::Function : Symbol::Flag::Subroutine);
6807     }
6808     if (!symbol.has<HostAssocDetails>()) {
6809       CheckPossibleBadForwardRef(symbol);
6810     }
6811   }
6812   currScope().InstantiateDerivedTypes();
6813   for (const auto &decl : decls) {
6814     if (const auto *statement{std::get_if<
6815             parser::Statement<common::Indirection<parser::StmtFunctionStmt>>>(
6816             &decl.u)}) {
6817       AnalyzeStmtFunctionStmt(statement->statement.value());
6818     }
6819   }
6820   // TODO: what about instantiations in BLOCK?
6821   CheckSaveStmts();
6822   CheckCommonBlocks();
6823   if (!inInterfaceBlock()) {
6824     // TODO: warn for the case where the EQUIVALENCE statement is in a
6825     // procedure declaration in an interface block
6826     CheckEquivalenceSets();
6827   }
6828 }
6829 
6830 // Analyze the bodies of statement functions now that the symbols in this
6831 // specification part have been fully declared and implicitly typed.
6832 void ResolveNamesVisitor::AnalyzeStmtFunctionStmt(
6833     const parser::StmtFunctionStmt &stmtFunc) {
6834   Symbol *symbol{std::get<parser::Name>(stmtFunc.t).symbol};
6835   if (!symbol || !symbol->has<SubprogramDetails>()) {
6836     return;
6837   }
6838   auto &details{symbol->get<SubprogramDetails>()};
6839   auto expr{AnalyzeExpr(
6840       context(), std::get<parser::Scalar<parser::Expr>>(stmtFunc.t))};
6841   if (!expr) {
6842     context().SetError(*symbol);
6843     return;
6844   }
6845   if (auto type{evaluate::DynamicType::From(*symbol)}) {
6846     auto converted{ConvertToType(*type, std::move(*expr))};
6847     if (!converted) {
6848       context().SetError(*symbol);
6849       return;
6850     }
6851     details.set_stmtFunction(std::move(*converted));
6852   } else {
6853     details.set_stmtFunction(std::move(*expr));
6854   }
6855 }
6856 
6857 void ResolveNamesVisitor::CheckImports() {
6858   auto &scope{currScope()};
6859   switch (scope.GetImportKind()) {
6860   case common::ImportKind::None:
6861     break;
6862   case common::ImportKind::All:
6863     // C8102: all entities in host must not be hidden
6864     for (const auto &pair : scope.parent()) {
6865       auto &name{pair.first};
6866       std::optional<SourceName> scopeName{scope.GetName()};
6867       if (!scopeName || name != *scopeName) {
6868         CheckImport(prevImportStmt_.value(), name);
6869       }
6870     }
6871     break;
6872   case common::ImportKind::Default:
6873   case common::ImportKind::Only:
6874     // C8102: entities named in IMPORT must not be hidden
6875     for (auto &name : scope.importNames()) {
6876       CheckImport(name, name);
6877     }
6878     break;
6879   }
6880 }
6881 
6882 void ResolveNamesVisitor::CheckImport(
6883     const SourceName &location, const SourceName &name) {
6884   if (auto *symbol{FindInScope(name)}) {
6885     const Symbol &ultimate{symbol->GetUltimate()};
6886     if (&ultimate.owner() == &currScope()) {
6887       Say(location, "'%s' from host is not accessible"_err_en_US, name)
6888           .Attach(symbol->name(), "'%s' is hidden by this entity"_en_US,
6889               symbol->name());
6890     }
6891   }
6892 }
6893 
6894 bool ResolveNamesVisitor::Pre(const parser::ImplicitStmt &x) {
6895   return CheckNotInBlock("IMPLICIT") && // C1107
6896       ImplicitRulesVisitor::Pre(x);
6897 }
6898 
6899 void ResolveNamesVisitor::Post(const parser::PointerObject &x) {
6900   std::visit(common::visitors{
6901                  [&](const parser::Name &x) { ResolveName(x); },
6902                  [&](const parser::StructureComponent &x) {
6903                    ResolveStructureComponent(x);
6904                  },
6905              },
6906       x.u);
6907 }
6908 void ResolveNamesVisitor::Post(const parser::AllocateObject &x) {
6909   std::visit(common::visitors{
6910                  [&](const parser::Name &x) { ResolveName(x); },
6911                  [&](const parser::StructureComponent &x) {
6912                    ResolveStructureComponent(x);
6913                  },
6914              },
6915       x.u);
6916 }
6917 
6918 bool ResolveNamesVisitor::Pre(const parser::PointerAssignmentStmt &x) {
6919   const auto &dataRef{std::get<parser::DataRef>(x.t)};
6920   const auto &bounds{std::get<parser::PointerAssignmentStmt::Bounds>(x.t)};
6921   const auto &expr{std::get<parser::Expr>(x.t)};
6922   ResolveDataRef(dataRef);
6923   Walk(bounds);
6924   // Resolve unrestricted specific intrinsic procedures as in "p => cos".
6925   if (const parser::Name * name{parser::Unwrap<parser::Name>(expr)}) {
6926     if (NameIsKnownOrIntrinsic(*name)) {
6927       // If the name is known because it is an object entity from a host
6928       // procedure, create a host associated symbol.
6929       if (Symbol * symbol{name->symbol}; symbol &&
6930           symbol->GetUltimate().has<ObjectEntityDetails>() &&
6931           IsUplevelReference(*symbol)) {
6932         MakeHostAssocSymbol(*name, *symbol);
6933       }
6934       return false;
6935     }
6936   }
6937   Walk(expr);
6938   return false;
6939 }
6940 void ResolveNamesVisitor::Post(const parser::Designator &x) {
6941   ResolveDesignator(x);
6942 }
6943 
6944 void ResolveNamesVisitor::Post(const parser::ProcComponentRef &x) {
6945   ResolveStructureComponent(x.v.thing);
6946 }
6947 void ResolveNamesVisitor::Post(const parser::TypeGuardStmt &x) {
6948   DeclTypeSpecVisitor::Post(x);
6949   ConstructVisitor::Post(x);
6950 }
6951 bool ResolveNamesVisitor::Pre(const parser::StmtFunctionStmt &x) {
6952   CheckNotInBlock("STATEMENT FUNCTION"); // C1107
6953   if (HandleStmtFunction(x)) {
6954     return false;
6955   } else {
6956     // This is an array element assignment: resolve names of indices
6957     const auto &names{std::get<std::list<parser::Name>>(x.t)};
6958     for (auto &name : names) {
6959       ResolveName(name);
6960     }
6961     return true;
6962   }
6963 }
6964 
6965 bool ResolveNamesVisitor::Pre(const parser::DefinedOpName &x) {
6966   const parser::Name &name{x.v};
6967   if (FindSymbol(name)) {
6968     // OK
6969   } else if (IsLogicalConstant(context(), name.source)) {
6970     Say(name,
6971         "Logical constant '%s' may not be used as a defined operator"_err_en_US);
6972   } else {
6973     // Resolved later in expression semantics
6974     MakePlaceholder(name, MiscDetails::Kind::TypeBoundDefinedOp);
6975   }
6976   return false;
6977 }
6978 
6979 void ResolveNamesVisitor::Post(const parser::AssignStmt &x) {
6980   if (auto *name{ResolveName(std::get<parser::Name>(x.t))}) {
6981     ConvertToObjectEntity(DEREF(name->symbol));
6982   }
6983 }
6984 void ResolveNamesVisitor::Post(const parser::AssignedGotoStmt &x) {
6985   if (auto *name{ResolveName(std::get<parser::Name>(x.t))}) {
6986     ConvertToObjectEntity(DEREF(name->symbol));
6987   }
6988 }
6989 
6990 bool ResolveNamesVisitor::Pre(const parser::ProgramUnit &x) {
6991   if (std::holds_alternative<common::Indirection<parser::CompilerDirective>>(
6992           x.u)) {
6993     // TODO: global directives
6994     return true;
6995   }
6996   auto root{ProgramTree::Build(x)};
6997   SetScope(topScope_);
6998   ResolveSpecificationParts(root);
6999   FinishSpecificationParts(root);
7000   inExecutionPart_ = true;
7001   ResolveExecutionParts(root);
7002   inExecutionPart_ = false;
7003   ResolveAccParts(context(), x);
7004   ResolveOmpParts(context(), x);
7005   return false;
7006 }
7007 
7008 // References to procedures need to record that their symbols are known
7009 // to be procedures, so that they don't get converted to objects by default.
7010 class ExecutionPartSkimmer {
7011 public:
7012   explicit ExecutionPartSkimmer(ResolveNamesVisitor &resolver)
7013       : resolver_{resolver} {}
7014 
7015   void Walk(const parser::ExecutionPart *exec) {
7016     if (exec) {
7017       parser::Walk(*exec, *this);
7018     }
7019   }
7020 
7021   template <typename A> bool Pre(const A &) { return true; }
7022   template <typename A> void Post(const A &) {}
7023   void Post(const parser::FunctionReference &fr) {
7024     resolver_.NoteExecutablePartCall(Symbol::Flag::Function, fr.v);
7025   }
7026   void Post(const parser::CallStmt &cs) {
7027     resolver_.NoteExecutablePartCall(Symbol::Flag::Subroutine, cs.v);
7028   }
7029 
7030 private:
7031   ResolveNamesVisitor &resolver_;
7032 };
7033 
7034 // Build the scope tree and resolve names in the specification parts of this
7035 // node and its children
7036 void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) {
7037   if (node.isSpecificationPartResolved()) {
7038     return; // been here already
7039   }
7040   node.set_isSpecificationPartResolved();
7041   if (!BeginScopeForNode(node)) {
7042     return; // an error prevented scope from being created
7043   }
7044   Scope &scope{currScope()};
7045   node.set_scope(scope);
7046   AddSubpNames(node);
7047   std::visit(
7048       [&](const auto *x) {
7049         if (x) {
7050           Walk(*x);
7051         }
7052       },
7053       node.stmt());
7054   Walk(node.spec());
7055   // If this is a function, convert result to an object. This is to prevent the
7056   // result from being converted later to a function symbol if it is called
7057   // inside the function.
7058   // If the result is function pointer, then ConvertToObjectEntity will not
7059   // convert the result to an object, and calling the symbol inside the function
7060   // will result in calls to the result pointer.
7061   // A function cannot be called recursively if RESULT was not used to define a
7062   // distinct result name (15.6.2.2 point 4.).
7063   if (Symbol * symbol{scope.symbol()}) {
7064     if (auto *details{symbol->detailsIf<SubprogramDetails>()}) {
7065       if (details->isFunction()) {
7066         ConvertToObjectEntity(const_cast<Symbol &>(details->result()));
7067       }
7068     }
7069   }
7070   if (node.IsModule()) {
7071     ApplyDefaultAccess();
7072   }
7073   for (auto &child : node.children()) {
7074     ResolveSpecificationParts(child);
7075   }
7076   ExecutionPartSkimmer{*this}.Walk(node.exec());
7077   EndScopeForNode(node);
7078   // Ensure that every object entity has a type.
7079   for (auto &pair : *node.scope()) {
7080     ApplyImplicitRules(*pair.second);
7081   }
7082 }
7083 
7084 // Add SubprogramNameDetails symbols for module and internal subprograms and
7085 // their ENTRY statements.
7086 void ResolveNamesVisitor::AddSubpNames(ProgramTree &node) {
7087   auto kind{
7088       node.IsModule() ? SubprogramKind::Module : SubprogramKind::Internal};
7089   for (auto &child : node.children()) {
7090     auto &symbol{MakeSymbol(child.name(), SubprogramNameDetails{kind, child})};
7091     auto childKind{child.GetKind()};
7092     if (childKind == ProgramTree::Kind::Function) {
7093       symbol.set(Symbol::Flag::Function);
7094     } else if (childKind == ProgramTree::Kind::Subroutine) {
7095       symbol.set(Symbol::Flag::Subroutine);
7096     }
7097     for (const auto &entryStmt : child.entryStmts()) {
7098       SubprogramNameDetails details{kind, child};
7099       details.set_isEntryStmt();
7100       auto &symbol{
7101           MakeSymbol(std::get<parser::Name>(entryStmt->t), std::move(details))};
7102       symbol.set(child.GetSubpFlag());
7103     }
7104   }
7105   for (const auto &generic : node.genericSpecs()) {
7106     if (const auto *name{std::get_if<parser::Name>(&generic->u)}) {
7107       if (currScope().find(name->source) != currScope().end()) {
7108         // If this scope has both a generic interface and a contained
7109         // subprogram with the same name, create the generic's symbol
7110         // now so that any other generics of the same name that are pulled
7111         // into scope later via USE association will properly merge instead
7112         // of raising a bogus error due a conflict with the subprogram.
7113         CreateGeneric(*generic);
7114       }
7115     }
7116   }
7117 }
7118 
7119 // Push a new scope for this node or return false on error.
7120 bool ResolveNamesVisitor::BeginScopeForNode(const ProgramTree &node) {
7121   switch (node.GetKind()) {
7122     SWITCH_COVERS_ALL_CASES
7123   case ProgramTree::Kind::Program:
7124     PushScope(Scope::Kind::MainProgram,
7125         &MakeSymbol(node.name(), MainProgramDetails{}));
7126     return true;
7127   case ProgramTree::Kind::Function:
7128   case ProgramTree::Kind::Subroutine:
7129     return BeginSubprogram(
7130         node.name(), node.GetSubpFlag(), node.HasModulePrefix());
7131   case ProgramTree::Kind::MpSubprogram:
7132     return BeginMpSubprogram(node.name());
7133   case ProgramTree::Kind::Module:
7134     BeginModule(node.name(), false);
7135     return true;
7136   case ProgramTree::Kind::Submodule:
7137     return BeginSubmodule(node.name(), node.GetParentId());
7138   case ProgramTree::Kind::BlockData:
7139     PushBlockDataScope(node.name());
7140     return true;
7141   }
7142 }
7143 
7144 void ResolveNamesVisitor::EndScopeForNode(const ProgramTree &node) {
7145   EndSubprogram();
7146 }
7147 
7148 // Some analyses and checks, such as the processing of initializers of
7149 // pointers, are deferred until all of the pertinent specification parts
7150 // have been visited.  This deferred processing enables the use of forward
7151 // references in these circumstances.
7152 class DeferredCheckVisitor {
7153 public:
7154   explicit DeferredCheckVisitor(ResolveNamesVisitor &resolver)
7155       : resolver_{resolver} {}
7156 
7157   template <typename A> void Walk(const A &x) { parser::Walk(x, *this); }
7158 
7159   template <typename A> bool Pre(const A &) { return true; }
7160   template <typename A> void Post(const A &) {}
7161 
7162   void Post(const parser::DerivedTypeStmt &x) {
7163     const auto &name{std::get<parser::Name>(x.t)};
7164     if (Symbol * symbol{name.symbol}) {
7165       if (Scope * scope{symbol->scope()}) {
7166         if (scope->IsDerivedType()) {
7167           resolver_.PushScope(*scope);
7168           pushedScope_ = true;
7169         }
7170       }
7171     }
7172   }
7173   void Post(const parser::EndTypeStmt &) {
7174     if (pushedScope_) {
7175       resolver_.PopScope();
7176       pushedScope_ = false;
7177     }
7178   }
7179 
7180   void Post(const parser::ProcInterface &pi) {
7181     if (const auto *name{std::get_if<parser::Name>(&pi.u)}) {
7182       resolver_.CheckExplicitInterface(*name);
7183     }
7184   }
7185   bool Pre(const parser::EntityDecl &decl) {
7186     Init(std::get<parser::Name>(decl.t),
7187         std::get<std::optional<parser::Initialization>>(decl.t));
7188     return false;
7189   }
7190   bool Pre(const parser::ComponentDecl &decl) {
7191     Init(std::get<parser::Name>(decl.t),
7192         std::get<std::optional<parser::Initialization>>(decl.t));
7193     return false;
7194   }
7195   bool Pre(const parser::ProcDecl &decl) {
7196     if (const auto &init{
7197             std::get<std::optional<parser::ProcPointerInit>>(decl.t)}) {
7198       resolver_.PointerInitialization(std::get<parser::Name>(decl.t), *init);
7199     }
7200     return false;
7201   }
7202   void Post(const parser::TypeBoundProcedureStmt::WithInterface &tbps) {
7203     resolver_.CheckExplicitInterface(tbps.interfaceName);
7204   }
7205   void Post(const parser::TypeBoundProcedureStmt::WithoutInterface &tbps) {
7206     if (pushedScope_) {
7207       resolver_.CheckBindings(tbps);
7208     }
7209   }
7210 
7211 private:
7212   void Init(const parser::Name &name,
7213       const std::optional<parser::Initialization> &init) {
7214     if (init) {
7215       if (const auto *target{
7216               std::get_if<parser::InitialDataTarget>(&init->u)}) {
7217         resolver_.PointerInitialization(name, *target);
7218       }
7219     }
7220   }
7221 
7222   ResolveNamesVisitor &resolver_;
7223   bool pushedScope_{false};
7224 };
7225 
7226 // Perform checks and completions that need to happen after all of
7227 // the specification parts but before any of the execution parts.
7228 void ResolveNamesVisitor::FinishSpecificationParts(const ProgramTree &node) {
7229   if (!node.scope()) {
7230     return; // error occurred creating scope
7231   }
7232   SetScope(*node.scope());
7233   // The initializers of pointers, the default initializers of pointer
7234   // components, and non-deferred type-bound procedure bindings have not
7235   // yet been traversed.
7236   // We do that now, when any (formerly) forward references that appear
7237   // in those initializers will resolve to the right symbols without
7238   // incurring spurious errors with IMPLICIT NONE.
7239   DeferredCheckVisitor{*this}.Walk(node.spec());
7240   DeferredCheckVisitor{*this}.Walk(node.exec()); // for BLOCK
7241   for (Scope &childScope : currScope().children()) {
7242     if (childScope.IsParameterizedDerivedTypeInstantiation()) {
7243       FinishDerivedTypeInstantiation(childScope);
7244     }
7245   }
7246   for (const auto &child : node.children()) {
7247     FinishSpecificationParts(child);
7248   }
7249 }
7250 
7251 // Duplicate and fold component object pointer default initializer designators
7252 // using the actual type parameter values of each particular instantiation.
7253 // Validation is done later in declaration checking.
7254 void ResolveNamesVisitor::FinishDerivedTypeInstantiation(Scope &scope) {
7255   CHECK(scope.IsDerivedType() && !scope.symbol());
7256   if (DerivedTypeSpec * spec{scope.derivedTypeSpec()}) {
7257     spec->Instantiate(currScope());
7258     const Symbol &origTypeSymbol{spec->typeSymbol()};
7259     if (const Scope * origTypeScope{origTypeSymbol.scope()}) {
7260       CHECK(origTypeScope->IsDerivedType() &&
7261           origTypeScope->symbol() == &origTypeSymbol);
7262       auto &foldingContext{GetFoldingContext()};
7263       auto restorer{foldingContext.WithPDTInstance(*spec)};
7264       for (auto &pair : scope) {
7265         Symbol &comp{*pair.second};
7266         const Symbol &origComp{DEREF(FindInScope(*origTypeScope, comp.name()))};
7267         if (IsPointer(comp)) {
7268           if (auto *details{comp.detailsIf<ObjectEntityDetails>()}) {
7269             auto origDetails{origComp.get<ObjectEntityDetails>()};
7270             if (const MaybeExpr & init{origDetails.init()}) {
7271               SomeExpr newInit{*init};
7272               MaybeExpr folded{
7273                   evaluate::Fold(foldingContext, std::move(newInit))};
7274               details->set_init(std::move(folded));
7275             }
7276           }
7277         }
7278       }
7279     }
7280   }
7281 }
7282 
7283 // Resolve names in the execution part of this node and its children
7284 void ResolveNamesVisitor::ResolveExecutionParts(const ProgramTree &node) {
7285   if (!node.scope()) {
7286     return; // error occurred creating scope
7287   }
7288   SetScope(*node.scope());
7289   if (const auto *exec{node.exec()}) {
7290     Walk(*exec);
7291   }
7292   PopScope(); // converts unclassified entities into objects
7293   for (const auto &child : node.children()) {
7294     ResolveExecutionParts(child);
7295   }
7296 }
7297 
7298 void ResolveNamesVisitor::Post(const parser::Program &) {
7299   // ensure that all temps were deallocated
7300   CHECK(!attrs_);
7301   CHECK(!GetDeclTypeSpec());
7302 }
7303 
7304 // A singleton instance of the scope -> IMPLICIT rules mapping is
7305 // shared by all instances of ResolveNamesVisitor and accessed by this
7306 // pointer when the visitors (other than the top-level original) are
7307 // constructed.
7308 static ImplicitRulesMap *sharedImplicitRulesMap{nullptr};
7309 
7310 bool ResolveNames(
7311     SemanticsContext &context, const parser::Program &program, Scope &top) {
7312   ImplicitRulesMap implicitRulesMap;
7313   auto restorer{common::ScopedSet(sharedImplicitRulesMap, &implicitRulesMap)};
7314   ResolveNamesVisitor{context, implicitRulesMap, top}.Walk(program);
7315   return !context.AnyFatalError();
7316 }
7317 
7318 // Processes a module (but not internal) function when it is referenced
7319 // in a specification expression in a sibling procedure.
7320 void ResolveSpecificationParts(
7321     SemanticsContext &context, const Symbol &subprogram) {
7322   auto originalLocation{context.location()};
7323   ResolveNamesVisitor visitor{
7324       context, DEREF(sharedImplicitRulesMap), context.globalScope()};
7325   const auto &details{subprogram.get<SubprogramNameDetails>()};
7326   ProgramTree &node{details.node()};
7327   const Scope &moduleScope{subprogram.owner()};
7328   visitor.SetScope(const_cast<Scope &>(moduleScope));
7329   visitor.ResolveSpecificationParts(node);
7330   context.set_location(std::move(originalLocation));
7331 }
7332 
7333 } // namespace Fortran::semantics
7334