1 //===-- lib/semantics/resolve-names.cpp -----------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "resolve-names.h"
10 #include "assignment.h"
11 #include "check-omp-structure.h"
13 #include "program-tree.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/common.h"
22 #include "flang/evaluate/fold.h"
23 #include "flang/evaluate/intrinsics.h"
24 #include "flang/evaluate/tools.h"
25 #include "flang/evaluate/type.h"
26 #include "flang/parser/parse-tree-visitor.h"
27 #include "flang/parser/parse-tree.h"
28 #include "flang/parser/tools.h"
29 #include "flang/semantics/attr.h"
30 #include "flang/semantics/expression.h"
31 #include "flang/semantics/scope.h"
32 #include "flang/semantics/semantics.h"
33 #include "flang/semantics/symbol.h"
34 #include "flang/semantics/tools.h"
35 #include "flang/semantics/type.h"
42 namespace Fortran::semantics {
44 using namespace parser::literals;
46 template<typename T> using Indirection = common::Indirection<T>;
47 using Message = parser::Message;
48 using Messages = parser::Messages;
49 using MessageFixedText = parser::MessageFixedText;
50 using MessageFormattedText = parser::MessageFormattedText;
52 class ResolveNamesVisitor;
54 // ImplicitRules maps initial character of identifier to the DeclTypeSpec
55 // representing the implicit type; std::nullopt if none.
56 // It also records the presence of IMPLICIT NONE statements.
57 // When inheritFromParent is set, defaults come from the parent rules.
60 ImplicitRules(SemanticsContext &context, ImplicitRules *parent)
61 : parent_{parent}, context_{context} {
62 inheritFromParent_ = parent != nullptr;
64 bool isImplicitNoneType() const;
65 bool isImplicitNoneExternal() const;
66 void set_isImplicitNoneType(bool x) { isImplicitNoneType_ = x; }
67 void set_isImplicitNoneExternal(bool x) { isImplicitNoneExternal_ = x; }
68 void set_inheritFromParent(bool x) { inheritFromParent_ = x; }
69 // Get the implicit type for identifiers starting with ch. May be null.
70 const DeclTypeSpec *GetType(char ch) const;
71 // Record the implicit type for the range of characters [fromLetter,
73 void SetTypeMapping(const DeclTypeSpec &type, parser::Location fromLetter,
74 parser::Location toLetter);
77 static char Incr(char ch);
79 ImplicitRules *parent_;
80 SemanticsContext &context_;
81 bool inheritFromParent_{false}; // look in parent if not specified here
82 bool isImplicitNoneType_{false};
83 bool isImplicitNoneExternal_{false};
84 // map_ contains the mapping between letters and types that were defined
85 // by the IMPLICIT statements of the related scope. It does not contain
86 // the default Fortran mappings nor the mapping defined in parents.
87 std::map<char, common::Reference<const DeclTypeSpec>> map_;
89 friend std::ostream &operator<<(std::ostream &, const ImplicitRules &);
90 friend void ShowImplicitRule(std::ostream &, const ImplicitRules &, char);
93 // Track statement source locations and save messages.
94 class MessageHandler {
96 MessageHandler() { DIE("MessageHandler: default-constructed"); }
97 explicit MessageHandler(SemanticsContext &c) : context_{&c} {}
98 Messages &messages() { return context_->messages(); };
99 const std::optional<SourceName> &currStmtSource() {
100 return context_->location();
102 void set_currStmtSource(const std::optional<SourceName> &source) {
103 context_->set_location(source);
106 // Emit a message associated with the current statement source.
107 Message &Say(MessageFixedText &&);
108 Message &Say(MessageFormattedText &&);
109 // Emit a message about a SourceName
110 Message &Say(const SourceName &, MessageFixedText &&);
111 // Emit a formatted message associated with a source location.
112 template<typename... A>
113 Message &Say(const SourceName &source, MessageFixedText &&msg, A &&... args) {
114 return context_->Say(source, std::move(msg), std::forward<A>(args)...);
118 SemanticsContext *context_;
121 // Inheritance graph for the parse tree visitation classes that follow:
124 // | + DeclTypeSpecVisitor
125 // | + ImplicitRulesVisitor
126 // | + ScopeHandler -----------+--+
127 // | + ModuleVisitor ========|==+
128 // | + InterfaceVisitor | |
129 // | +-+ SubprogramVisitor ==|==+
130 // + ArraySpecVisitor | |
131 // + DeclarationVisitor <--------+ |
132 // + ConstructVisitor |
133 // + ResolveNamesVisitor <------+
137 BaseVisitor() { DIE("BaseVisitor: default-constructed"); }
138 BaseVisitor(SemanticsContext &c, ResolveNamesVisitor &v)
139 : this_{&v}, context_{&c}, messageHandler_{c} {}
140 template<typename T> void Walk(const T &);
142 MessageHandler &messageHandler() { return messageHandler_; }
143 const std::optional<SourceName> &currStmtSource() {
144 return context_->location();
146 SemanticsContext &context() const { return *context_; }
147 evaluate::FoldingContext &GetFoldingContext() const {
148 return context_->foldingContext();
151 // Make a placeholder symbol for a Name that otherwise wouldn't have one.
152 // It is not in any scope and always has MiscDetails.
153 void MakePlaceholder(const parser::Name &, MiscDetails::Kind);
155 template<typename T> common::IfNoLvalue<T, T> FoldExpr(T &&expr) {
156 return evaluate::Fold(GetFoldingContext(), std::move(expr));
159 template<typename T> MaybeExpr EvaluateExpr(const T &expr) {
160 return FoldExpr(AnalyzeExpr(*context_, expr));
164 MaybeExpr EvaluateConvertedExpr(
165 const Symbol &symbol, const T &expr, parser::CharBlock source) {
166 if (context().HasError(symbol)) {
169 auto maybeExpr{AnalyzeExpr(*context_, expr)};
173 auto exprType{maybeExpr->GetType()};
174 auto converted{evaluate::ConvertToType(symbol, std::move(*maybeExpr))};
178 "Initialization expression could not be converted to declared type of '%s' from %s"_err_en_US,
179 symbol.name(), exprType->AsFortran());
182 "Initialization expression could not be converted to declared type of '%s'"_err_en_US,
187 return FoldExpr(std::move(*converted));
190 template<typename T> MaybeIntExpr EvaluateIntExpr(const T &expr) {
191 if (MaybeExpr maybeExpr{EvaluateExpr(expr)}) {
192 if (auto *intExpr{evaluate::UnwrapExpr<SomeIntExpr>(*maybeExpr)}) {
193 return std::move(*intExpr);
200 MaybeSubscriptIntExpr EvaluateSubscriptIntExpr(const T &expr) {
201 if (MaybeIntExpr maybeIntExpr{EvaluateIntExpr(expr)}) {
202 return FoldExpr(evaluate::ConvertToType<evaluate::SubscriptInteger>(
203 std::move(*maybeIntExpr)));
209 template<typename... A> Message &Say(A &&... args) {
210 return messageHandler_.Say(std::forward<A>(args)...);
212 template<typename... A>
214 const parser::Name &name, MessageFixedText &&text, const A &... args) {
215 return messageHandler_.Say(name.source, std::move(text), args...);
219 ResolveNamesVisitor *this_;
220 SemanticsContext *context_;
221 MessageHandler messageHandler_;
224 // Provide Post methods to collect attributes into a member variable.
225 class AttrsVisitor : public virtual BaseVisitor {
227 bool BeginAttrs(); // always returns true
230 bool SetPassNameOn(Symbol &);
231 bool SetBindNameOn(Symbol &);
232 void Post(const parser::LanguageBindingSpec &);
233 bool Pre(const parser::AccessSpec &);
234 bool Pre(const parser::IntentSpec &);
235 bool Pre(const parser::Pass &);
237 // Simple case: encountering CLASSNAME causes ATTRNAME to be set.
238 #define HANDLE_ATTR_CLASS(CLASSNAME, ATTRNAME) \
239 bool Pre(const parser::CLASSNAME &) { \
240 attrs_->set(Attr::ATTRNAME); \
243 HANDLE_ATTR_CLASS(PrefixSpec::Elemental, ELEMENTAL)
244 HANDLE_ATTR_CLASS(PrefixSpec::Impure, IMPURE)
245 HANDLE_ATTR_CLASS(PrefixSpec::Module, MODULE)
246 HANDLE_ATTR_CLASS(PrefixSpec::Non_Recursive, NON_RECURSIVE)
247 HANDLE_ATTR_CLASS(PrefixSpec::Pure, PURE)
248 HANDLE_ATTR_CLASS(PrefixSpec::Recursive, RECURSIVE)
249 HANDLE_ATTR_CLASS(TypeAttrSpec::BindC, BIND_C)
250 HANDLE_ATTR_CLASS(BindAttr::Deferred, DEFERRED)
251 HANDLE_ATTR_CLASS(BindAttr::Non_Overridable, NON_OVERRIDABLE)
252 HANDLE_ATTR_CLASS(Abstract, ABSTRACT)
253 HANDLE_ATTR_CLASS(Allocatable, ALLOCATABLE)
254 HANDLE_ATTR_CLASS(Asynchronous, ASYNCHRONOUS)
255 HANDLE_ATTR_CLASS(Contiguous, CONTIGUOUS)
256 HANDLE_ATTR_CLASS(External, EXTERNAL)
257 HANDLE_ATTR_CLASS(Intrinsic, INTRINSIC)
258 HANDLE_ATTR_CLASS(NoPass, NOPASS)
259 HANDLE_ATTR_CLASS(Optional, OPTIONAL)
260 HANDLE_ATTR_CLASS(Parameter, PARAMETER)
261 HANDLE_ATTR_CLASS(Pointer, POINTER)
262 HANDLE_ATTR_CLASS(Protected, PROTECTED)
263 HANDLE_ATTR_CLASS(Save, SAVE)
264 HANDLE_ATTR_CLASS(Target, TARGET)
265 HANDLE_ATTR_CLASS(Value, VALUE)
266 HANDLE_ATTR_CLASS(Volatile, VOLATILE)
267 #undef HANDLE_ATTR_CLASS
270 std::optional<Attrs> attrs_;
272 Attr AccessSpecToAttr(const parser::AccessSpec &x) {
274 case parser::AccessSpec::Kind::Public: return Attr::PUBLIC;
275 case parser::AccessSpec::Kind::Private: return Attr::PRIVATE;
277 common::die("unreachable"); // suppress g++ warning
279 Attr IntentSpecToAttr(const parser::IntentSpec &x) {
281 case parser::IntentSpec::Intent::In: return Attr::INTENT_IN;
282 case parser::IntentSpec::Intent::Out: return Attr::INTENT_OUT;
283 case parser::IntentSpec::Intent::InOut: return Attr::INTENT_INOUT;
285 common::die("unreachable"); // suppress g++ warning
289 MaybeExpr bindName_; // from BIND(C, NAME="...")
290 std::optional<SourceName> passName_; // from PASS(...)
293 // Find and create types from declaration-type-spec nodes.
294 class DeclTypeSpecVisitor : public AttrsVisitor {
296 using AttrsVisitor::Post;
297 using AttrsVisitor::Pre;
298 void Post(const parser::IntrinsicTypeSpec::DoublePrecision &);
299 void Post(const parser::IntrinsicTypeSpec::DoubleComplex &);
300 void Post(const parser::DeclarationTypeSpec::ClassStar &);
301 void Post(const parser::DeclarationTypeSpec::TypeStar &);
302 bool Pre(const parser::TypeGuardStmt &);
303 void Post(const parser::TypeGuardStmt &);
304 void Post(const parser::TypeSpec &);
308 bool expectDeclTypeSpec{false}; // should see decl-type-spec only when true
309 const DeclTypeSpec *declTypeSpec{nullptr};
311 DerivedTypeSpec *type{nullptr};
312 DeclTypeSpec::Category category{DeclTypeSpec::TypeDerived};
314 bool allowForwardReferenceToDerivedType{false};
317 bool allowForwardReferenceToDerivedType() const {
318 return state_.allowForwardReferenceToDerivedType;
320 void set_allowForwardReferenceToDerivedType(bool yes) {
321 state_.allowForwardReferenceToDerivedType = yes;
324 // Walk the parse tree of a type spec and return the DeclTypeSpec for it.
326 const DeclTypeSpec *ProcessTypeSpec(const T &x, bool allowForward = false) {
327 auto restorer{common::ScopedSet(state_, State{})};
328 set_allowForwardReferenceToDerivedType(allowForward);
331 const auto *type{GetDeclTypeSpec()};
336 const DeclTypeSpec *GetDeclTypeSpec();
337 void BeginDeclTypeSpec();
338 void EndDeclTypeSpec();
339 void SetDeclTypeSpec(const DeclTypeSpec &);
340 void SetDeclTypeSpecCategory(DeclTypeSpec::Category);
341 DeclTypeSpec::Category GetDeclTypeSpecCategory() const {
342 return state_.derived.category;
344 KindExpr GetKindParamExpr(
345 TypeCategory, const std::optional<parser::KindSelector> &);
350 void MakeNumericType(TypeCategory, int kind);
353 // Visit ImplicitStmt and related parse tree nodes and updates implicit rules.
354 class ImplicitRulesVisitor : public DeclTypeSpecVisitor {
356 using DeclTypeSpecVisitor::Post;
357 using DeclTypeSpecVisitor::Pre;
358 using ImplicitNoneNameSpec = parser::ImplicitStmt::ImplicitNoneNameSpec;
360 void Post(const parser::ParameterStmt &);
361 bool Pre(const parser::ImplicitStmt &);
362 bool Pre(const parser::LetterSpec &);
363 bool Pre(const parser::ImplicitSpec &);
364 void Post(const parser::ImplicitSpec &);
366 ImplicitRules &implicitRules() { return *implicitRules_; }
367 const ImplicitRules &implicitRules() const { return *implicitRules_; }
368 bool isImplicitNoneType() const {
369 return implicitRules().isImplicitNoneType();
371 bool isImplicitNoneExternal() const {
372 return implicitRules().isImplicitNoneExternal();
376 void BeginScope(const Scope &);
377 void SetScope(const Scope &);
380 // scope -> implicit rules for that scope
381 std::map<const Scope *, ImplicitRules> implicitRulesMap_;
382 // implicit rules in effect for current scope
383 ImplicitRules *implicitRules_{nullptr};
384 std::optional<SourceName> prevImplicit_;
385 std::optional<SourceName> prevImplicitNone_;
386 std::optional<SourceName> prevImplicitNoneType_;
387 std::optional<SourceName> prevParameterStmt_;
389 bool HandleImplicitNone(const std::list<ImplicitNoneNameSpec> &nameSpecs);
392 // Track array specifications. They can occur in AttrSpec, EntityDecl,
393 // ObjectDecl, DimensionStmt, CommonBlockObject, or BasedPointerStmt.
394 // 1. INTEGER, DIMENSION(10) :: x
395 // 2. INTEGER :: x(10)
396 // 3. ALLOCATABLE :: x(:)
397 // 4. DIMENSION :: x(10)
399 // 6. BasedPointerStmt
400 class ArraySpecVisitor : public virtual BaseVisitor {
402 void Post(const parser::ArraySpec &);
403 void Post(const parser::ComponentArraySpec &);
404 void Post(const parser::CoarraySpec &);
405 void Post(const parser::AttrSpec &) { PostAttrSpec(); }
406 void Post(const parser::ComponentAttrSpec &) { PostAttrSpec(); }
409 const ArraySpec &arraySpec();
410 const ArraySpec &coarraySpec();
411 void BeginArraySpec();
413 void ClearArraySpec() { arraySpec_.clear(); }
414 void ClearCoarraySpec() { coarraySpec_.clear(); }
417 // arraySpec_/coarraySpec_ are populated from any ArraySpec/CoarraySpec
418 ArraySpec arraySpec_;
419 ArraySpec coarraySpec_;
420 // When an ArraySpec is under an AttrSpec or ComponentAttrSpec, it is moved
421 // into attrArraySpec_
422 ArraySpec attrArraySpec_;
423 ArraySpec attrCoarraySpec_;
428 // Manage a stack of Scopes
429 class ScopeHandler : public ImplicitRulesVisitor {
431 using ImplicitRulesVisitor::Post;
432 using ImplicitRulesVisitor::Pre;
434 Scope &currScope() { return DEREF(currScope_); }
435 // The enclosing scope, skipping blocks and derived types.
436 Scope &InclusiveScope();
437 // The global scope, containing program units.
438 Scope &GlobalScope();
440 // Create a new scope and push it on the scope stack.
441 void PushScope(Scope::Kind kind, Symbol *symbol);
442 void PushScope(Scope &scope);
444 void SetScope(Scope &);
446 template<typename T> bool Pre(const parser::Statement<T> &x) {
447 messageHandler().set_currStmtSource(x.source);
448 currScope_->AddSourceRange(x.source);
451 template<typename T> void Post(const parser::Statement<T> &) {
452 messageHandler().set_currStmtSource(std::nullopt);
455 // Special messages: already declared; referencing symbol's declaration;
456 // about a type; two names & locations
457 void SayAlreadyDeclared(const parser::Name &, Symbol &);
458 void SayAlreadyDeclared(const SourceName &, Symbol &);
459 void SayAlreadyDeclared(const SourceName &, const SourceName &);
461 const parser::Name &, Symbol &, MessageFixedText &&, MessageFixedText &&);
462 void SayWithDecl(const parser::Name &, Symbol &, MessageFixedText &&);
463 void SayLocalMustBeVariable(const parser::Name &, Symbol &);
464 void SayDerivedType(const SourceName &, MessageFixedText &&, const Scope &);
465 void Say2(const SourceName &, MessageFixedText &&, const SourceName &,
466 MessageFixedText &&);
468 const SourceName &, MessageFixedText &&, Symbol &, MessageFixedText &&);
470 const parser::Name &, MessageFixedText &&, Symbol &, MessageFixedText &&);
472 // Search for symbol by name in current, parent derived type, and
474 Symbol *FindSymbol(const parser::Name &);
475 Symbol *FindSymbol(const Scope &, const parser::Name &);
476 // Search for name only in scope, not in enclosing scopes.
477 Symbol *FindInScope(const Scope &, const parser::Name &);
478 Symbol *FindInScope(const Scope &, const SourceName &);
479 // Search for name in a derived type scope and its parents.
480 Symbol *FindInTypeOrParents(const Scope &, const parser::Name &);
481 Symbol *FindInTypeOrParents(const parser::Name &);
482 void EraseSymbol(const parser::Name &);
483 void EraseSymbol(const Symbol &symbol) { currScope().erase(symbol.name()); }
484 // Make a new symbol with the name and attrs of an existing one
485 Symbol &CopySymbol(const SourceName &, const Symbol &);
487 // Make symbols in the current or named scope
488 Symbol &MakeSymbol(Scope &, const SourceName &, Attrs);
489 Symbol &MakeSymbol(const SourceName &, Attrs = Attrs{});
490 Symbol &MakeSymbol(const parser::Name &, Attrs = Attrs{});
493 common::IfNoLvalue<Symbol &, D> MakeSymbol(
494 const parser::Name &name, D &&details) {
495 return MakeSymbol(name, Attrs{}, std::move(details));
499 common::IfNoLvalue<Symbol &, D> MakeSymbol(
500 const parser::Name &name, const Attrs &attrs, D &&details) {
501 return Resolve(name, MakeSymbol(name.source, attrs, std::move(details)));
505 common::IfNoLvalue<Symbol &, D> MakeSymbol(
506 const SourceName &name, const Attrs &attrs, D &&details) {
507 // Note: don't use FindSymbol here. If this is a derived type scope,
508 // we want to detect whether the name is already declared as a component.
509 auto *symbol{FindInScope(currScope(), name)};
511 symbol = &MakeSymbol(name, attrs);
512 symbol->set_details(std::move(details));
515 if constexpr (std::is_same_v<DerivedTypeDetails, D>) {
516 if (auto *d{symbol->detailsIf<GenericDetails>()}) {
517 if (!d->specific()) {
518 // derived type with same name as a generic
519 auto *derivedType{d->derivedType()};
522 &currScope().MakeSymbol(name, attrs, std::move(details));
523 d->set_derivedType(*derivedType);
525 SayAlreadyDeclared(name, *derivedType);
531 if (symbol->CanReplaceDetails(details)) {
532 // update the existing symbol
533 symbol->attrs() |= attrs;
534 symbol->set_details(std::move(details));
536 } else if constexpr (std::is_same_v<UnknownDetails, D>) {
537 symbol->attrs() |= attrs;
540 SayAlreadyDeclared(name, *symbol);
541 // replace the old symbol with a new one with correct details
542 EraseSymbol(*symbol);
543 auto &result{MakeSymbol(name, attrs, std::move(details))};
544 context().SetError(result);
549 void MakeExternal(Symbol &);
552 // Apply the implicit type rules to this symbol.
553 void ApplyImplicitRules(Symbol &);
554 const DeclTypeSpec *GetImplicitType(Symbol &);
555 bool ConvertToObjectEntity(Symbol &);
556 bool ConvertToProcEntity(Symbol &);
558 const DeclTypeSpec &MakeNumericType(
559 TypeCategory, const std::optional<parser::KindSelector> &);
560 const DeclTypeSpec &MakeLogicalType(
561 const std::optional<parser::KindSelector> &);
564 Scope *currScope_{nullptr};
567 class ModuleVisitor : public virtual ScopeHandler {
569 bool Pre(const parser::AccessStmt &);
570 bool Pre(const parser::Only &);
571 bool Pre(const parser::Rename::Names &);
572 bool Pre(const parser::Rename::Operators &);
573 bool Pre(const parser::UseStmt &);
574 void Post(const parser::UseStmt &);
576 void BeginModule(const parser::Name &, bool isSubmodule);
577 bool BeginSubmodule(const parser::Name &, const parser::ParentIdentifier &);
578 void ApplyDefaultAccess();
581 // The default access spec for this module.
582 Attr defaultAccess_{Attr::PUBLIC};
583 // The location of the last AccessStmt without access-ids, if any.
584 std::optional<SourceName> prevAccessStmt_;
585 // The scope of the module during a UseStmt
586 const Scope *useModuleScope_{nullptr};
588 Symbol &SetAccess(const SourceName &, Attr attr, Symbol * = nullptr);
589 // A rename in a USE statement: local => use
590 struct SymbolRename {
591 Symbol *local{nullptr};
592 Symbol *use{nullptr};
594 // Record a use from useModuleScope_ of use Name/Symbol as local Name/Symbol
595 SymbolRename AddUse(const SourceName &localName, const SourceName &useName);
596 SymbolRename AddUse(const SourceName &, const SourceName &, Symbol *);
597 void AddUse(const SourceName &, Symbol &localSymbol, const Symbol &useSymbol);
598 void AddUse(const GenericSpecInfo &);
599 Scope *FindModule(const parser::Name &, Scope *ancestor = nullptr);
602 class InterfaceVisitor : public virtual ScopeHandler {
604 bool Pre(const parser::InterfaceStmt &);
605 void Post(const parser::EndInterfaceStmt &);
606 bool Pre(const parser::GenericSpec &);
607 bool Pre(const parser::ProcedureStmt &);
608 bool Pre(const parser::GenericStmt &);
609 void Post(const parser::GenericStmt &);
611 bool inInterfaceBlock() const;
612 bool isGeneric() const;
613 bool isAbstract() const;
616 GenericDetails &GetGenericDetails();
617 // Add to generic the symbol for the subprogram with the same name
618 void CheckGenericProcedures(Symbol &);
621 // A new GenericInfo is pushed for each interface block and generic stmt
623 GenericInfo(bool isInterface, bool isAbstract = false)
624 : isInterface{isInterface}, isAbstract{isAbstract} {}
625 bool isInterface; // in interface block
626 bool isAbstract; // in abstract interface block
627 Symbol *symbol{nullptr}; // the generic symbol being defined
629 std::stack<GenericInfo> genericInfo_;
630 const GenericInfo &GetGenericInfo() const { return genericInfo_.top(); }
631 void SetGenericSymbol(Symbol &symbol) { genericInfo_.top().symbol = &symbol; }
633 using ProcedureKind = parser::ProcedureStmt::Kind;
634 // mapping of generic to its specific proc names and kinds
635 std::multimap<Symbol *, std::pair<const parser::Name *, ProcedureKind>>
638 void AddSpecificProcs(const std::list<parser::Name> &, ProcedureKind);
639 void ResolveSpecificsInGeneric(Symbol &generic);
642 class SubprogramVisitor : public virtual ScopeHandler, public InterfaceVisitor {
644 bool HandleStmtFunction(const parser::StmtFunctionStmt &);
645 bool Pre(const parser::SubroutineStmt &);
646 void Post(const parser::SubroutineStmt &);
647 bool Pre(const parser::FunctionStmt &);
648 void Post(const parser::FunctionStmt &);
649 bool Pre(const parser::InterfaceBody::Subroutine &);
650 void Post(const parser::InterfaceBody::Subroutine &);
651 bool Pre(const parser::InterfaceBody::Function &);
652 void Post(const parser::InterfaceBody::Function &);
653 bool Pre(const parser::Suffix &);
654 bool Pre(const parser::PrefixSpec &);
655 void Post(const parser::ImplicitPart &);
657 bool BeginSubprogram(
658 const parser::Name &, Symbol::Flag, bool hasModulePrefix = false);
659 bool BeginMpSubprogram(const parser::Name &);
660 void PushBlockDataScope(const parser::Name &);
661 void EndSubprogram();
664 // Set when we see a stmt function that is really an array element assignment
665 bool badStmtFuncFound_{false};
668 // Info about the current function: parse tree of the type in the PrefixSpec;
669 // name and symbol of the function result from the Suffix; source location.
671 const parser::DeclarationTypeSpec *parsedType{nullptr};
672 const parser::Name *resultName{nullptr};
673 Symbol *resultSymbol{nullptr};
674 std::optional<SourceName> source;
677 // Create a subprogram symbol in the current scope and push a new scope.
678 Symbol &PushSubprogramScope(const parser::Name &, Symbol::Flag);
679 Symbol *GetSpecificFromGeneric(const parser::Name &);
680 SubprogramDetails &PostSubprogramStmt(const parser::Name &);
683 class DeclarationVisitor : public ArraySpecVisitor,
684 public virtual ScopeHandler {
686 using ArraySpecVisitor::Post;
687 using ScopeHandler::Post;
688 using ScopeHandler::Pre;
690 bool Pre(const parser::Initialization &);
691 void Post(const parser::EntityDecl &);
692 void Post(const parser::ObjectDecl &);
693 void Post(const parser::PointerDecl &);
694 bool Pre(const parser::BindStmt &) { return BeginAttrs(); }
695 void Post(const parser::BindStmt &) { EndAttrs(); }
696 bool Pre(const parser::BindEntity &);
697 bool Pre(const parser::NamedConstantDef &);
698 bool Pre(const parser::NamedConstant &);
699 void Post(const parser::EnumDef &);
700 bool Pre(const parser::Enumerator &);
701 bool Pre(const parser::AsynchronousStmt &);
702 bool Pre(const parser::ContiguousStmt &);
703 bool Pre(const parser::ExternalStmt &);
704 bool Pre(const parser::IntentStmt &);
705 bool Pre(const parser::IntrinsicStmt &);
706 bool Pre(const parser::OptionalStmt &);
707 bool Pre(const parser::ProtectedStmt &);
708 bool Pre(const parser::ValueStmt &);
709 bool Pre(const parser::VolatileStmt &);
710 bool Pre(const parser::AllocatableStmt &) {
711 objectDeclAttr_ = Attr::ALLOCATABLE;
714 void Post(const parser::AllocatableStmt &) { objectDeclAttr_ = std::nullopt; }
715 bool Pre(const parser::TargetStmt &) {
716 objectDeclAttr_ = Attr::TARGET;
719 void Post(const parser::TargetStmt &) { objectDeclAttr_ = std::nullopt; }
720 void Post(const parser::DimensionStmt::Declaration &);
721 void Post(const parser::CodimensionDecl &);
722 bool Pre(const parser::TypeDeclarationStmt &) { return BeginDecl(); }
723 void Post(const parser::TypeDeclarationStmt &) { EndDecl(); }
724 void Post(const parser::IntegerTypeSpec &);
725 void Post(const parser::IntrinsicTypeSpec::Real &);
726 void Post(const parser::IntrinsicTypeSpec::Complex &);
727 void Post(const parser::IntrinsicTypeSpec::Logical &);
728 void Post(const parser::IntrinsicTypeSpec::Character &);
729 void Post(const parser::CharSelector::LengthAndKind &);
730 void Post(const parser::CharLength &);
731 void Post(const parser::LengthSelector &);
732 bool Pre(const parser::KindParam &);
733 bool Pre(const parser::DeclarationTypeSpec::Type &);
734 bool Pre(const parser::DeclarationTypeSpec::Class &);
735 bool Pre(const parser::DeclarationTypeSpec::Record &);
736 void Post(const parser::DerivedTypeSpec &);
737 bool Pre(const parser::DerivedTypeDef &);
738 bool Pre(const parser::DerivedTypeStmt &);
739 void Post(const parser::DerivedTypeStmt &);
740 bool Pre(const parser::TypeParamDefStmt &) { return BeginDecl(); }
741 void Post(const parser::TypeParamDefStmt &);
742 bool Pre(const parser::TypeAttrSpec::Extends &);
743 bool Pre(const parser::PrivateStmt &);
744 bool Pre(const parser::SequenceStmt &);
745 bool Pre(const parser::ComponentDefStmt &) { return BeginDecl(); }
746 void Post(const parser::ComponentDefStmt &) { EndDecl(); }
747 void Post(const parser::ComponentDecl &);
748 bool Pre(const parser::ProcedureDeclarationStmt &);
749 void Post(const parser::ProcedureDeclarationStmt &);
750 bool Pre(const parser::DataComponentDefStmt &); // returns false
751 bool Pre(const parser::ProcComponentDefStmt &);
752 void Post(const parser::ProcComponentDefStmt &);
753 bool Pre(const parser::ProcPointerInit &);
754 void Post(const parser::ProcInterface &);
755 void Post(const parser::ProcDecl &);
756 bool Pre(const parser::TypeBoundProcedurePart &);
757 void Post(const parser::TypeBoundProcedurePart &);
758 void Post(const parser::ContainsStmt &);
759 bool Pre(const parser::TypeBoundProcBinding &) { return BeginAttrs(); }
760 void Post(const parser::TypeBoundProcBinding &) { EndAttrs(); }
761 void Post(const parser::TypeBoundProcedureStmt::WithoutInterface &);
762 void Post(const parser::TypeBoundProcedureStmt::WithInterface &);
763 void Post(const parser::FinalProcedureStmt &);
764 bool Pre(const parser::TypeBoundGenericStmt &);
765 bool Pre(const parser::AllocateStmt &);
766 void Post(const parser::AllocateStmt &);
767 bool Pre(const parser::StructureConstructor &);
768 bool Pre(const parser::NamelistStmt::Group &);
769 bool Pre(const parser::IoControlSpec &);
770 bool Pre(const parser::CommonStmt::Block &);
771 void Post(const parser::CommonStmt::Block &);
772 bool Pre(const parser::CommonBlockObject &);
773 void Post(const parser::CommonBlockObject &);
774 bool Pre(const parser::EquivalenceStmt &);
775 bool Pre(const parser::SaveStmt &);
776 bool Pre(const parser::BasedPointerStmt &);
778 void PointerInitialization(
779 const parser::Name &, const parser::InitialDataTarget &);
780 void PointerInitialization(
781 const parser::Name &, const parser::ProcPointerInit &);
782 void CheckExplicitInterface(const parser::Name &);
783 void CheckBindings(const parser::TypeBoundProcedureStmt::WithoutInterface &);
785 const parser::Name *ResolveDesignator(const parser::Designator &);
790 Symbol &DeclareObjectEntity(const parser::Name &, Attrs);
791 // Make sure that there's an entity in an enclosing scope called Name
792 Symbol &FindOrDeclareEnclosingEntity(const parser::Name &);
793 // Declare a LOCAL/LOCAL_INIT entity. If there isn't a type specified
794 // it comes from the entity in the containing scope, or implicit rules.
795 // Return pointer to the new symbol, or nullptr on error.
796 Symbol *DeclareLocalEntity(const parser::Name &);
797 // Declare a statement entity (e.g., an implied DO loop index).
798 // If there isn't a type specified, implicit rules apply.
799 // Return pointer to the new symbol, or nullptr on error.
800 Symbol *DeclareStatementEntity(
801 const parser::Name &, const std::optional<parser::IntegerTypeSpec> &);
802 bool CheckUseError(const parser::Name &);
803 void CheckAccessibility(const SourceName &, bool, Symbol &);
804 bool CheckAccessibleComponent(const SourceName &, const Symbol &);
805 void CheckCommonBlocks();
806 void CheckSaveStmts();
807 void CheckEquivalenceSets();
808 bool CheckNotInBlock(const char *);
809 bool NameIsKnownOrIntrinsic(const parser::Name &);
811 // Each of these returns a pointer to a resolved Name (i.e. with symbol)
812 // or nullptr in case of error.
813 const parser::Name *ResolveStructureComponent(
814 const parser::StructureComponent &);
815 const parser::Name *ResolveDataRef(const parser::DataRef &);
816 const parser::Name *ResolveVariable(const parser::Variable &);
817 const parser::Name *ResolveName(const parser::Name &);
818 bool PassesSharedLocalityChecks(const parser::Name &name, Symbol &symbol);
819 Symbol *NoteInterfaceName(const parser::Name &);
822 // The attribute corresponding to the statement containing an ObjectDecl
823 std::optional<Attr> objectDeclAttr_;
824 // Info about current character type while walking DeclTypeSpec.
825 // Also captures any "*length" specifier on an individual declaration.
827 std::optional<ParamValue> length;
828 std::optional<KindExpr> kind;
830 // Info about current derived type while walking DerivedTypeDef
832 const parser::Name *extends{nullptr}; // EXTENDS(name)
833 bool privateComps{false}; // components are private by default
834 bool privateBindings{false}; // bindings are private by default
835 bool sawContains{false}; // currently processing bindings
836 bool sequence{false}; // is a sequence type
837 const Symbol *type{nullptr}; // derived type being defined
839 // Collect equivalence sets and process at end of specification part
840 std::vector<const std::list<parser::EquivalenceObject> *> equivalenceSets_;
841 // Info about common blocks in the current scope
843 Symbol *curr{nullptr}; // common block currently being processed
844 std::set<SourceName> names; // names in any common block of scope
846 // Info about about SAVE statements and attributes in current scope
848 std::optional<SourceName> saveAll; // "SAVE" without entity list
849 std::set<SourceName> entities; // names of entities with save attr
850 std::set<SourceName> commons; // names of common blocks with save attr
852 // In a ProcedureDeclarationStmt or ProcComponentDefStmt, this is
853 // the interface name, if any.
854 const parser::Name *interfaceName_{nullptr};
855 // Map type-bound generic to binding names of its specific bindings
856 std::multimap<Symbol *, const parser::Name *> genericBindings_;
857 // Info about current ENUM
858 struct EnumeratorState {
859 // Enum value must hold inside a C_INT (7.6.2).
860 std::optional<int> value{0};
863 bool HandleAttributeStmt(Attr, const std::list<parser::Name> &);
864 Symbol &HandleAttributeStmt(Attr, const parser::Name &);
865 Symbol &DeclareUnknownEntity(const parser::Name &, Attrs);
866 Symbol &DeclareProcEntity(const parser::Name &, Attrs, const ProcInterface &);
867 void SetType(const parser::Name &, const DeclTypeSpec &);
868 std::optional<DerivedTypeSpec> ResolveDerivedType(const parser::Name &);
869 std::optional<DerivedTypeSpec> ResolveExtendsType(
870 const parser::Name &, const parser::Name *);
871 Symbol *MakeTypeSymbol(const SourceName &, Details &&);
872 Symbol *MakeTypeSymbol(const parser::Name &, Details &&);
873 bool OkToAddComponent(const parser::Name &, const Symbol * = nullptr);
874 ParamValue GetParamValue(
875 const parser::TypeParamValue &, common::TypeParamAttr attr);
876 Symbol &MakeCommonBlockSymbol(const parser::Name &);
877 void CheckCommonBlockDerivedType(const SourceName &, const Symbol &);
878 std::optional<MessageFixedText> CheckSaveAttr(const Symbol &);
879 Attrs HandleSaveName(const SourceName &, Attrs);
880 void AddSaveName(std::set<SourceName> &, const SourceName &);
881 void SetSaveAttr(Symbol &);
882 bool HandleUnrestrictedSpecificIntrinsicFunction(const parser::Name &);
883 const parser::Name *FindComponent(const parser::Name *, const parser::Name &);
884 void CheckInitialDataTarget(const Symbol &, const SomeExpr &, SourceName);
885 void CheckInitialProcTarget(const Symbol &, const parser::Name &, SourceName);
886 void Initialization(const parser::Name &, const parser::Initialization &,
887 bool inComponentDecl);
888 bool PassesLocalityChecks(const parser::Name &name, Symbol &symbol);
890 // Declare an object or procedure entity.
891 // T is one of: EntityDetails, ObjectEntityDetails, ProcEntityDetails
893 Symbol &DeclareEntity(const parser::Name &name, Attrs attrs) {
894 Symbol &symbol{MakeSymbol(name, attrs)};
895 if (symbol.has<T>()) {
897 } else if (symbol.has<UnknownDetails>()) {
898 symbol.set_details(T{});
899 } else if (auto *details{symbol.detailsIf<EntityDetails>()}) {
900 symbol.set_details(T{std::move(*details)});
901 } else if (std::is_same_v<EntityDetails, T> &&
902 (symbol.has<ObjectEntityDetails>() ||
903 symbol.has<ProcEntityDetails>())) {
905 } else if (auto *details{symbol.detailsIf<UseDetails>()}) {
907 "'%s' is use-associated from module '%s' and cannot be re-declared"_err_en_US,
908 name.source, details->module().name());
909 } else if (auto *details{symbol.detailsIf<SubprogramNameDetails>()}) {
910 if (details->kind() == SubprogramKind::Module) {
912 "Declaration of '%s' conflicts with its use as module procedure"_err_en_US,
913 symbol, "Module procedure definition"_en_US);
914 } else if (details->kind() == SubprogramKind::Internal) {
916 "Declaration of '%s' conflicts with its use as internal procedure"_err_en_US,
917 symbol, "Internal procedure definition"_en_US);
919 DIE("unexpected kind");
921 } else if (std::is_same_v<ObjectEntityDetails, T> &&
922 symbol.has<ProcEntityDetails>()) {
924 name, symbol, "'%s' is already declared as a procedure"_err_en_US);
925 } else if (std::is_same_v<ProcEntityDetails, T> &&
926 symbol.has<ObjectEntityDetails>()) {
928 name, symbol, "'%s' is already declared as an object"_err_en_US);
930 SayAlreadyDeclared(name, symbol);
936 // Resolve construct entities and statement entities.
937 // Check that construct names don't conflict with other names.
938 class ConstructVisitor : public virtual DeclarationVisitor {
940 bool Pre(const parser::ConcurrentHeader &);
941 bool Pre(const parser::LocalitySpec::Local &);
942 bool Pre(const parser::LocalitySpec::LocalInit &);
943 bool Pre(const parser::LocalitySpec::Shared &);
944 bool Pre(const parser::AcSpec &);
945 bool Pre(const parser::AcImpliedDo &);
946 bool Pre(const parser::DataImpliedDo &);
947 bool Pre(const parser::DataStmtObject &);
948 bool Pre(const parser::DoConstruct &);
949 void Post(const parser::DoConstruct &);
950 bool Pre(const parser::ForallConstruct &);
951 void Post(const parser::ForallConstruct &);
952 bool Pre(const parser::ForallStmt &);
953 void Post(const parser::ForallStmt &);
954 bool Pre(const parser::BlockStmt &);
955 bool Pre(const parser::EndBlockStmt &);
956 void Post(const parser::Selector &);
957 bool Pre(const parser::AssociateStmt &);
958 void Post(const parser::EndAssociateStmt &);
959 void Post(const parser::Association &);
960 void Post(const parser::SelectTypeStmt &);
961 bool Pre(const parser::SelectTypeConstruct &);
962 void Post(const parser::SelectTypeConstruct &);
963 bool Pre(const parser::SelectTypeConstruct::TypeCase &);
964 void Post(const parser::SelectTypeConstruct::TypeCase &);
965 void Post(const parser::TypeGuardStmt::Guard &);
966 bool Pre(const parser::ChangeTeamStmt &);
967 void Post(const parser::EndChangeTeamStmt &);
968 void Post(const parser::CoarrayAssociation &);
970 // Definitions of construct names
971 bool Pre(const parser::WhereConstructStmt &x) { return CheckDef(x.t); }
972 bool Pre(const parser::ForallConstructStmt &x) { return CheckDef(x.t); }
973 bool Pre(const parser::CriticalStmt &x) { return CheckDef(x.t); }
974 bool Pre(const parser::LabelDoStmt &) {
975 return false; // error recovery
977 bool Pre(const parser::NonLabelDoStmt &x) { return CheckDef(x.t); }
978 bool Pre(const parser::IfThenStmt &x) { return CheckDef(x.t); }
979 bool Pre(const parser::SelectCaseStmt &x) { return CheckDef(x.t); }
980 bool Pre(const parser::SelectRankConstruct &);
981 void Post(const parser::SelectRankConstruct &);
982 bool Pre(const parser::SelectRankStmt &x) {
983 return CheckDef(std::get<0>(x.t));
985 bool Pre(const parser::SelectTypeStmt &x) {
986 return CheckDef(std::get<0>(x.t));
989 // References to construct names
990 void Post(const parser::MaskedElsewhereStmt &x) { CheckRef(x.t); }
991 void Post(const parser::ElsewhereStmt &x) { CheckRef(x.v); }
992 void Post(const parser::EndWhereStmt &x) { CheckRef(x.v); }
993 void Post(const parser::EndForallStmt &x) { CheckRef(x.v); }
994 void Post(const parser::EndCriticalStmt &x) { CheckRef(x.v); }
995 void Post(const parser::EndDoStmt &x) { CheckRef(x.v); }
996 void Post(const parser::ElseIfStmt &x) { CheckRef(x.t); }
997 void Post(const parser::ElseStmt &x) { CheckRef(x.v); }
998 void Post(const parser::EndIfStmt &x) { CheckRef(x.v); }
999 void Post(const parser::CaseStmt &x) { CheckRef(x.t); }
1000 void Post(const parser::EndSelectStmt &x) { CheckRef(x.v); }
1001 void Post(const parser::SelectRankCaseStmt &x) { CheckRef(x.t); }
1002 void Post(const parser::TypeGuardStmt &x) { CheckRef(x.t); }
1003 void Post(const parser::CycleStmt &x) { CheckRef(x.v); }
1004 void Post(const parser::ExitStmt &x) { CheckRef(x.v); }
1007 // R1105 selector -> expr | variable
1008 // expr is set in either case unless there were errors
1011 Selector(const SourceName &source, MaybeExpr &&expr)
1012 : source{source}, expr{std::move(expr)} {}
1013 operator bool() const { return expr.has_value(); }
1014 parser::CharBlock source;
1017 // association -> [associate-name =>] selector
1018 struct Association {
1019 const parser::Name *name{nullptr};
1022 std::vector<Association> associationStack_;
1024 template<typename T> bool CheckDef(const T &t) {
1025 return CheckDef(std::get<std::optional<parser::Name>>(t));
1027 template<typename T> void CheckRef(const T &t) {
1028 CheckRef(std::get<std::optional<parser::Name>>(t));
1030 bool CheckDef(const std::optional<parser::Name> &);
1031 void CheckRef(const std::optional<parser::Name> &);
1032 const DeclTypeSpec &ToDeclTypeSpec(evaluate::DynamicType &&);
1033 const DeclTypeSpec &ToDeclTypeSpec(
1034 evaluate::DynamicType &&, MaybeSubscriptIntExpr &&length);
1035 Symbol *MakeAssocEntity();
1036 void SetTypeFromAssociation(Symbol &);
1037 void SetAttrsFromAssociation(Symbol &);
1038 Selector ResolveSelector(const parser::Selector &);
1039 void ResolveIndexName(const parser::ConcurrentControl &control);
1040 Association &GetCurrentAssociation();
1041 void PushAssociation();
1042 void PopAssociation();
1045 // Create scopes for OpenMP constructs
1046 class OmpVisitor : public virtual DeclarationVisitor {
1048 void AddOmpSourceRange(const parser::CharBlock &);
1050 static bool NeedsScope(const parser::OpenMPBlockConstruct &);
1052 bool Pre(const parser::OpenMPBlockConstruct &);
1053 void Post(const parser::OpenMPBlockConstruct &);
1054 bool Pre(const parser::OmpBeginBlockDirective &x) {
1055 AddOmpSourceRange(x.source);
1058 void Post(const parser::OmpBeginBlockDirective &) {
1059 messageHandler().set_currStmtSource(std::nullopt);
1061 bool Pre(const parser::OmpEndBlockDirective &x) {
1062 AddOmpSourceRange(x.source);
1065 void Post(const parser::OmpEndBlockDirective &) {
1066 messageHandler().set_currStmtSource(std::nullopt);
1069 bool Pre(const parser::OpenMPLoopConstruct &) {
1070 PushScope(Scope::Kind::Block, nullptr);
1073 void Post(const parser::OpenMPLoopConstruct &) { PopScope(); }
1074 bool Pre(const parser::OmpBeginLoopDirective &x) {
1075 AddOmpSourceRange(x.source);
1078 void Post(const parser::OmpBeginLoopDirective &) {
1079 messageHandler().set_currStmtSource(std::nullopt);
1081 bool Pre(const parser::OmpEndLoopDirective &x) {
1082 AddOmpSourceRange(x.source);
1085 void Post(const parser::OmpEndLoopDirective &) {
1086 messageHandler().set_currStmtSource(std::nullopt);
1089 bool Pre(const parser::OpenMPSectionsConstruct &) {
1090 PushScope(Scope::Kind::Block, nullptr);
1093 void Post(const parser::OpenMPSectionsConstruct &) { PopScope(); }
1094 bool Pre(const parser::OmpBeginSectionsDirective &x) {
1095 AddOmpSourceRange(x.source);
1098 void Post(const parser::OmpBeginSectionsDirective &) {
1099 messageHandler().set_currStmtSource(std::nullopt);
1101 bool Pre(const parser::OmpEndSectionsDirective &x) {
1102 AddOmpSourceRange(x.source);
1105 void Post(const parser::OmpEndSectionsDirective &) {
1106 messageHandler().set_currStmtSource(std::nullopt);
1110 bool OmpVisitor::NeedsScope(const parser::OpenMPBlockConstruct &x) {
1111 const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)};
1112 const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
1113 switch (beginDir.v) {
1114 case parser::OmpBlockDirective::Directive::TargetData:
1115 case parser::OmpBlockDirective::Directive::Master:
1116 case parser::OmpBlockDirective::Directive::Ordered: return false;
1117 default: return true;
1121 void OmpVisitor::AddOmpSourceRange(const parser::CharBlock &source) {
1122 messageHandler().set_currStmtSource(source);
1123 currScope().AddSourceRange(source);
1126 bool OmpVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
1127 if (NeedsScope(x)) {
1128 PushScope(Scope::Kind::Block, nullptr);
1133 void OmpVisitor::Post(const parser::OpenMPBlockConstruct &x) {
1134 if (NeedsScope(x)) {
1139 // Data-sharing and Data-mapping attributes for data-refs in OpenMP construct
1140 class OmpAttributeVisitor {
1142 explicit OmpAttributeVisitor(
1143 SemanticsContext &context, ResolveNamesVisitor &resolver)
1144 : context_{context}, resolver_{resolver} {}
1146 template<typename A> void Walk(const A &x) { parser::Walk(x, *this); }
1148 template<typename A> bool Pre(const A &) { return true; }
1149 template<typename A> void Post(const A &) {}
1151 bool Pre(const parser::OpenMPBlockConstruct &);
1152 void Post(const parser::OpenMPBlockConstruct &) { PopContext(); }
1153 void Post(const parser::OmpBeginBlockDirective &) {
1154 GetContext().withinConstruct = true;
1157 bool Pre(const parser::OpenMPLoopConstruct &);
1158 void Post(const parser::OpenMPLoopConstruct &) { PopContext(); }
1159 void Post(const parser::OmpBeginLoopDirective &) {
1160 GetContext().withinConstruct = true;
1163 bool Pre(const parser::OpenMPSectionsConstruct &);
1164 void Post(const parser::OpenMPSectionsConstruct &) { PopContext(); }
1166 bool Pre(const parser::OpenMPThreadprivate &);
1167 void Post(const parser::OpenMPThreadprivate &) { PopContext(); }
1169 // 2.15.3 Data-Sharing Attribute Clauses
1170 void Post(const parser::OmpDefaultClause &);
1171 bool Pre(const parser::OmpClause::Shared &x) {
1172 ResolveOmpObjectList(x.v, Symbol::Flag::OmpShared);
1175 bool Pre(const parser::OmpClause::Private &x) {
1176 ResolveOmpObjectList(x.v, Symbol::Flag::OmpPrivate);
1179 bool Pre(const parser::OmpClause::Firstprivate &x) {
1180 ResolveOmpObjectList(x.v, Symbol::Flag::OmpFirstPrivate);
1183 bool Pre(const parser::OmpClause::Lastprivate &x) {
1184 ResolveOmpObjectList(x.v, Symbol::Flag::OmpLastPrivate);
1188 void Post(const parser::Name &);
1192 OmpContext(const parser::CharBlock &source, OmpDirective d, Scope &s)
1193 : directiveSource{source}, directive{d}, scope{s} {}
1194 parser::CharBlock directiveSource;
1195 OmpDirective directive;
1197 // TODO: default DSA is implicitly determined in different ways
1198 Symbol::Flag defaultDSA{Symbol::Flag::OmpShared};
1199 // variables on Data-sharing attribute clauses
1200 std::map<const Symbol *, Symbol::Flag> objectWithDSA;
1201 bool withinConstruct{false};
1203 // back() is the top of the stack
1204 OmpContext &GetContext() {
1205 CHECK(!ompContext_.empty());
1206 return ompContext_.back();
1208 void PushContext(const parser::CharBlock &source, OmpDirective dir) {
1209 ompContext_.emplace_back(source, dir, context_.FindScope(source));
1211 void PopContext() { ompContext_.pop_back(); }
1212 void SetContextDirectiveSource(parser::CharBlock &dir) {
1213 GetContext().directiveSource = dir;
1215 void SetContextDirectiveEnum(OmpDirective dir) {
1216 GetContext().directive = dir;
1218 const Scope &currScope() { return GetContext().scope; }
1219 void SetContextDefaultDSA(Symbol::Flag flag) {
1220 GetContext().defaultDSA = flag;
1222 void AddToContextObjectWithDSA(const Symbol &symbol, Symbol::Flag flag) {
1223 GetContext().objectWithDSA.emplace(&symbol, flag);
1225 bool IsObjectWithDSA(const Symbol &symbol) {
1226 auto it{GetContext().objectWithDSA.find(&symbol)};
1227 return it != GetContext().objectWithDSA.end();
1230 Symbol &MakeAssocSymbol(const SourceName &name, Symbol &prev) {
1232 GetContext().scope.try_emplace(name, Attrs{}, HostAssocDetails{prev})};
1233 return *pair.first->second;
1236 static const parser::Name *GetDesignatorNameIfDataRef(
1237 const parser::Designator &designator) {
1238 const auto *dataRef{std::get_if<parser::DataRef>(&designator.u)};
1239 return dataRef ? std::get_if<parser::Name>(&dataRef->u) : nullptr;
1242 static constexpr Symbol::Flags dataSharingAttributeFlags{
1243 Symbol::Flag::OmpShared, Symbol::Flag::OmpPrivate,
1244 Symbol::Flag::OmpFirstPrivate, Symbol::Flag::OmpLastPrivate,
1245 Symbol::Flag::OmpReduction, Symbol::Flag::OmpLinear};
1247 static constexpr Symbol::Flags ompFlagsRequireNewSymbol{
1248 Symbol::Flag::OmpPrivate, Symbol::Flag::OmpLinear,
1249 Symbol::Flag::OmpFirstPrivate, Symbol::Flag::OmpLastPrivate,
1250 Symbol::Flag::OmpReduction};
1252 static constexpr Symbol::Flags ompFlagsRequireMark{
1253 Symbol::Flag::OmpThreadprivate};
1255 void AddDataSharingAttributeObject(SymbolRef object) {
1256 dataSharingAttributeObjects_.insert(object);
1258 void ClearDataSharingAttributeObjects() {
1259 dataSharingAttributeObjects_.clear();
1261 bool HasDataSharingAttributeObject(const Symbol &);
1263 void ResolveOmpObjectList(const parser::OmpObjectList &, Symbol::Flag);
1264 void ResolveOmpObject(const parser::OmpObject &, Symbol::Flag);
1265 Symbol *ResolveOmp(const parser::Name &, Symbol::Flag);
1266 Symbol *ResolveOmp(Symbol &, Symbol::Flag);
1267 Symbol *ResolveOmpCommonBlockName(const parser::Name *);
1268 Symbol *DeclarePrivateAccessEntity(const parser::Name &, Symbol::Flag);
1269 Symbol *DeclarePrivateAccessEntity(Symbol &, Symbol::Flag);
1270 Symbol *DeclareOrMarkOtherAccessEntity(const parser::Name &, Symbol::Flag);
1271 Symbol *DeclareOrMarkOtherAccessEntity(Symbol &, Symbol::Flag);
1272 void CheckMultipleAppearances(
1273 const parser::Name &, const Symbol &, Symbol::Flag);
1274 SymbolSet dataSharingAttributeObjects_; // on one directive
1276 SemanticsContext &context_;
1277 ResolveNamesVisitor &resolver_;
1278 std::vector<OmpContext> ompContext_; // used as a stack
1281 // Walk the parse tree and resolve names to symbols.
1282 class ResolveNamesVisitor : public virtual ScopeHandler,
1283 public ModuleVisitor,
1284 public SubprogramVisitor,
1285 public ConstructVisitor,
1288 using ArraySpecVisitor::Post;
1289 using ConstructVisitor::Post;
1290 using ConstructVisitor::Pre;
1291 using DeclarationVisitor::Post;
1292 using DeclarationVisitor::Pre;
1293 using ImplicitRulesVisitor::Post;
1294 using ImplicitRulesVisitor::Pre;
1295 using InterfaceVisitor::Post;
1296 using InterfaceVisitor::Pre;
1297 using ModuleVisitor::Post;
1298 using ModuleVisitor::Pre;
1299 using OmpVisitor::Post;
1300 using OmpVisitor::Pre;
1301 using ScopeHandler::Post;
1302 using ScopeHandler::Pre;
1303 using SubprogramVisitor::Post;
1304 using SubprogramVisitor::Pre;
1306 ResolveNamesVisitor(SemanticsContext &context) : BaseVisitor{context, *this} {
1307 PushScope(context.globalScope());
1310 // Default action for a parse tree node is to visit children.
1311 template<typename T> bool Pre(const T &) { return true; }
1312 template<typename T> void Post(const T &) {}
1314 bool Pre(const parser::SpecificationPart &);
1315 void Post(const parser::Program &);
1316 bool Pre(const parser::ImplicitStmt &);
1317 void Post(const parser::PointerObject &);
1318 void Post(const parser::AllocateObject &);
1319 bool Pre(const parser::PointerAssignmentStmt &);
1320 void Post(const parser::Designator &);
1321 template<typename A, typename B>
1322 void Post(const parser::LoopBounds<A, B> &x) {
1323 ResolveName(*parser::Unwrap<parser::Name>(x.name));
1325 void Post(const parser::ProcComponentRef &);
1326 bool Pre(const parser::ActualArg &);
1327 bool Pre(const parser::FunctionReference &);
1328 bool Pre(const parser::CallStmt &);
1329 bool Pre(const parser::ImportStmt &);
1330 void Post(const parser::TypeGuardStmt &);
1331 bool Pre(const parser::StmtFunctionStmt &);
1332 bool Pre(const parser::DefinedOpName &);
1333 bool Pre(const parser::ProgramUnit &);
1335 // These nodes should never be reached: they are handled in ProgramUnit
1336 bool Pre(const parser::MainProgram &) { DIE("unreachable"); }
1337 bool Pre(const parser::FunctionSubprogram &) { DIE("unreachable"); }
1338 bool Pre(const parser::SubroutineSubprogram &) { DIE("unreachable"); }
1339 bool Pre(const parser::SeparateModuleSubprogram &) { DIE("unreachable"); }
1340 bool Pre(const parser::Module &) { DIE("unreachable"); }
1341 bool Pre(const parser::Submodule &) { DIE("unreachable"); }
1342 bool Pre(const parser::BlockData &) { DIE("unreachable"); }
1344 void NoteExecutablePartCall(Symbol::Flag, const parser::Call &);
1347 // Kind of procedure we are expecting to see in a ProcedureDesignator
1348 std::optional<Symbol::Flag> expectedProcFlag_;
1349 std::optional<SourceName> prevImportStmt_;
1351 void PreSpecificationConstruct(const parser::SpecificationConstruct &);
1352 void CreateGeneric(const parser::GenericSpec &);
1353 void FinishSpecificationPart();
1354 void CheckImports();
1355 void CheckImport(const SourceName &, const SourceName &);
1356 void HandleCall(Symbol::Flag, const parser::Call &);
1357 void HandleProcedureName(Symbol::Flag, const parser::Name &);
1358 bool SetProcFlag(const parser::Name &, Symbol &, Symbol::Flag);
1359 void ResolveSpecificationParts(ProgramTree &);
1360 void AddSubpNames(const ProgramTree &);
1361 bool BeginScope(const ProgramTree &);
1362 void FinishSpecificationParts(const ProgramTree &);
1363 void FinishDerivedTypeInstantiation(Scope &);
1364 void ResolveExecutionParts(const ProgramTree &);
1367 // ImplicitRules implementation
1369 bool ImplicitRules::isImplicitNoneType() const {
1370 if (isImplicitNoneType_) {
1372 } else if (map_.empty() && inheritFromParent_) {
1373 return parent_->isImplicitNoneType();
1375 return false; // default if not specified
1379 bool ImplicitRules::isImplicitNoneExternal() const {
1380 if (isImplicitNoneExternal_) {
1382 } else if (inheritFromParent_) {
1383 return parent_->isImplicitNoneExternal();
1385 return false; // default if not specified
1389 const DeclTypeSpec *ImplicitRules::GetType(char ch) const {
1390 if (isImplicitNoneType_) {
1392 } else if (auto it{map_.find(ch)}; it != map_.end()) {
1393 return &*it->second;
1394 } else if (inheritFromParent_) {
1395 return parent_->GetType(ch);
1396 } else if (ch >= 'i' && ch <= 'n') {
1397 return &context_.MakeNumericType(TypeCategory::Integer);
1398 } else if (ch >= 'a' && ch <= 'z') {
1399 return &context_.MakeNumericType(TypeCategory::Real);
1405 void ImplicitRules::SetTypeMapping(const DeclTypeSpec &type,
1406 parser::Location fromLetter, parser::Location toLetter) {
1407 for (char ch = *fromLetter; ch; ch = ImplicitRules::Incr(ch)) {
1408 auto res{map_.emplace(ch, type)};
1410 context_.Say(parser::CharBlock{fromLetter},
1411 "More than one implicit type specified for '%c'"_err_en_US, ch);
1413 if (ch == *toLetter) {
1419 // Return the next char after ch in a way that works for ASCII or EBCDIC.
1420 // Return '\0' for the char after 'z'.
1421 char ImplicitRules::Incr(char ch) {
1423 case 'i': return 'j';
1424 case 'r': return 's';
1425 case 'z': return '\0';
1426 default: return ch + 1;
1430 std::ostream &operator<<(std::ostream &o, const ImplicitRules &implicitRules) {
1431 o << "ImplicitRules:\n";
1432 for (char ch = 'a'; ch; ch = ImplicitRules::Incr(ch)) {
1433 ShowImplicitRule(o, implicitRules, ch);
1435 ShowImplicitRule(o, implicitRules, '_');
1436 ShowImplicitRule(o, implicitRules, '$');
1437 ShowImplicitRule(o, implicitRules, '@');
1440 void ShowImplicitRule(
1441 std::ostream &o, const ImplicitRules &implicitRules, char ch) {
1442 auto it{implicitRules.map_.find(ch)};
1443 if (it != implicitRules.map_.end()) {
1444 o << " " << ch << ": " << *it->second << '\n';
1448 template<typename T> void BaseVisitor::Walk(const T &x) {
1449 parser::Walk(x, *this_);
1452 void BaseVisitor::MakePlaceholder(
1453 const parser::Name &name, MiscDetails::Kind kind) {
1455 name.symbol = &context_->globalScope().MakeSymbol(
1456 name.source, Attrs{}, MiscDetails{kind});
1460 // AttrsVisitor implementation
1462 bool AttrsVisitor::BeginAttrs() {
1464 attrs_ = std::make_optional<Attrs>();
1467 Attrs AttrsVisitor::GetAttrs() {
1471 Attrs AttrsVisitor::EndAttrs() {
1472 Attrs result{GetAttrs()};
1474 passName_ = std::nullopt;
1479 bool AttrsVisitor::SetPassNameOn(Symbol &symbol) {
1485 [&](ProcEntityDetails &x) { x.set_passName(*passName_); },
1486 [&](ProcBindingDetails &x) { x.set_passName(*passName_); },
1487 [](auto &) { common::die("unexpected pass name"); },
1493 bool AttrsVisitor::SetBindNameOn(Symbol &symbol) {
1499 [&](EntityDetails &x) { x.set_bindName(std::move(bindName_)); },
1500 [&](ObjectEntityDetails &x) { x.set_bindName(std::move(bindName_)); },
1501 [&](ProcEntityDetails &x) { x.set_bindName(std::move(bindName_)); },
1502 [&](SubprogramDetails &x) { x.set_bindName(std::move(bindName_)); },
1503 [&](CommonBlockDetails &x) { x.set_bindName(std::move(bindName_)); },
1504 [](auto &) { common::die("unexpected bind name"); },
1510 void AttrsVisitor::Post(const parser::LanguageBindingSpec &x) {
1512 attrs_->set(Attr::BIND_C);
1514 bindName_ = EvaluateExpr(*x.v);
1517 bool AttrsVisitor::Pre(const parser::AccessSpec &x) {
1518 attrs_->set(AccessSpecToAttr(x));
1521 bool AttrsVisitor::Pre(const parser::IntentSpec &x) {
1523 attrs_->set(IntentSpecToAttr(x));
1526 bool AttrsVisitor::Pre(const parser::Pass &x) {
1528 passName_ = x.v->source;
1529 MakePlaceholder(*x.v, MiscDetails::Kind::PassName);
1531 attrs_->set(Attr::PASS);
1536 // DeclTypeSpecVisitor implementation
1538 const DeclTypeSpec *DeclTypeSpecVisitor::GetDeclTypeSpec() {
1539 return state_.declTypeSpec;
1542 void DeclTypeSpecVisitor::BeginDeclTypeSpec() {
1543 CHECK(!state_.expectDeclTypeSpec);
1544 CHECK(!state_.declTypeSpec);
1545 state_.expectDeclTypeSpec = true;
1547 void DeclTypeSpecVisitor::EndDeclTypeSpec() {
1548 CHECK(state_.expectDeclTypeSpec);
1552 void DeclTypeSpecVisitor::SetDeclTypeSpecCategory(
1553 DeclTypeSpec::Category category) {
1554 CHECK(state_.expectDeclTypeSpec);
1555 state_.derived.category = category;
1558 bool DeclTypeSpecVisitor::Pre(const parser::TypeGuardStmt &) {
1559 BeginDeclTypeSpec();
1562 void DeclTypeSpecVisitor::Post(const parser::TypeGuardStmt &) {
1566 void DeclTypeSpecVisitor::Post(const parser::TypeSpec &typeSpec) {
1567 // Record the resolved DeclTypeSpec in the parse tree for use by
1568 // expression semantics if the DeclTypeSpec is a valid TypeSpec.
1569 // The grammar ensures that it's an intrinsic or derived type spec,
1570 // not TYPE(*) or CLASS(*) or CLASS(T).
1571 if (const DeclTypeSpec * spec{state_.declTypeSpec}) {
1572 switch (spec->category()) {
1573 case DeclTypeSpec::Numeric:
1574 case DeclTypeSpec::Logical:
1575 case DeclTypeSpec::Character: typeSpec.declTypeSpec = spec; break;
1576 case DeclTypeSpec::TypeDerived:
1577 if (const DerivedTypeSpec * derived{spec->AsDerived()}) {
1578 if (derived->typeSymbol().attrs().test(Attr::ABSTRACT)) {
1579 Say("ABSTRACT derived type may not be used here"_err_en_US);
1581 typeSpec.declTypeSpec = spec;
1584 default: CRASH_NO_CASE;
1589 void DeclTypeSpecVisitor::Post(
1590 const parser::IntrinsicTypeSpec::DoublePrecision &) {
1591 MakeNumericType(TypeCategory::Real, context().doublePrecisionKind());
1593 void DeclTypeSpecVisitor::Post(
1594 const parser::IntrinsicTypeSpec::DoubleComplex &) {
1595 MakeNumericType(TypeCategory::Complex, context().doublePrecisionKind());
1597 void DeclTypeSpecVisitor::MakeNumericType(TypeCategory category, int kind) {
1598 SetDeclTypeSpec(context().MakeNumericType(category, kind));
1601 void DeclTypeSpecVisitor::Post(const parser::DeclarationTypeSpec::ClassStar &) {
1602 SetDeclTypeSpec(context().globalScope().MakeClassStarType());
1604 void DeclTypeSpecVisitor::Post(const parser::DeclarationTypeSpec::TypeStar &) {
1605 SetDeclTypeSpec(context().globalScope().MakeTypeStarType());
1608 // Check that we're expecting to see a DeclTypeSpec (and haven't seen one yet)
1609 // and save it in state_.declTypeSpec.
1610 void DeclTypeSpecVisitor::SetDeclTypeSpec(const DeclTypeSpec &declTypeSpec) {
1611 CHECK(state_.expectDeclTypeSpec);
1612 CHECK(!state_.declTypeSpec);
1613 state_.declTypeSpec = &declTypeSpec;
1616 KindExpr DeclTypeSpecVisitor::GetKindParamExpr(
1617 TypeCategory category, const std::optional<parser::KindSelector> &kind) {
1618 return AnalyzeKindSelector(context(), category, kind);
1621 // MessageHandler implementation
1623 Message &MessageHandler::Say(MessageFixedText &&msg) {
1624 return context_->Say(currStmtSource().value(), std::move(msg));
1626 Message &MessageHandler::Say(MessageFormattedText &&msg) {
1627 return context_->Say(currStmtSource().value(), std::move(msg));
1629 Message &MessageHandler::Say(const SourceName &name, MessageFixedText &&msg) {
1630 return Say(name, std::move(msg), name);
1633 // ImplicitRulesVisitor implementation
1635 void ImplicitRulesVisitor::Post(const parser::ParameterStmt &) {
1636 prevParameterStmt_ = currStmtSource();
1639 bool ImplicitRulesVisitor::Pre(const parser::ImplicitStmt &x) {
1640 bool result{std::visit(
1642 [&](const std::list<ImplicitNoneNameSpec> &y) {
1643 return HandleImplicitNone(y);
1645 [&](const std::list<parser::ImplicitSpec> &) {
1646 if (prevImplicitNoneType_) {
1647 Say("IMPLICIT statement after IMPLICIT NONE or "
1648 "IMPLICIT NONE(TYPE) statement"_err_en_US);
1651 implicitRules().set_isImplicitNoneType(false);
1657 prevImplicit_ = currStmtSource();
1661 bool ImplicitRulesVisitor::Pre(const parser::LetterSpec &x) {
1662 auto loLoc{std::get<parser::Location>(x.t)};
1664 if (auto hiLocOpt{std::get<std::optional<parser::Location>>(x.t)}) {
1666 if (*hiLoc < *loLoc) {
1667 Say(hiLoc, "'%s' does not follow '%s' alphabetically"_err_en_US,
1668 std::string(hiLoc, 1), std::string(loLoc, 1));
1672 implicitRules().SetTypeMapping(*GetDeclTypeSpec(), loLoc, hiLoc);
1676 bool ImplicitRulesVisitor::Pre(const parser::ImplicitSpec &) {
1677 BeginDeclTypeSpec();
1678 set_allowForwardReferenceToDerivedType(true);
1682 void ImplicitRulesVisitor::Post(const parser::ImplicitSpec &) {
1686 void ImplicitRulesVisitor::SetScope(const Scope &scope) {
1687 implicitRules_ = &implicitRulesMap_.at(&scope);
1688 prevImplicit_ = std::nullopt;
1689 prevImplicitNone_ = std::nullopt;
1690 prevImplicitNoneType_ = std::nullopt;
1691 prevParameterStmt_ = std::nullopt;
1693 void ImplicitRulesVisitor::BeginScope(const Scope &scope) {
1694 // find or create implicit rules for this scope
1695 implicitRulesMap_.try_emplace(&scope, context(), implicitRules_);
1699 // TODO: for all of these errors, reference previous statement too
1700 bool ImplicitRulesVisitor::HandleImplicitNone(
1701 const std::list<ImplicitNoneNameSpec> &nameSpecs) {
1702 if (prevImplicitNone_) {
1703 Say("More than one IMPLICIT NONE statement"_err_en_US);
1704 Say(*prevImplicitNone_, "Previous IMPLICIT NONE statement"_en_US);
1707 if (prevParameterStmt_) {
1708 Say("IMPLICIT NONE statement after PARAMETER statement"_err_en_US);
1711 prevImplicitNone_ = currStmtSource();
1712 if (nameSpecs.empty()) {
1713 prevImplicitNoneType_ = currStmtSource();
1714 implicitRules().set_isImplicitNoneType(true);
1715 if (prevImplicit_) {
1716 Say("IMPLICIT NONE statement after IMPLICIT statement"_err_en_US);
1722 for (const auto noneSpec : nameSpecs) {
1724 case ImplicitNoneNameSpec::External:
1725 implicitRules().set_isImplicitNoneExternal(true);
1728 case ImplicitNoneNameSpec::Type:
1729 prevImplicitNoneType_ = currStmtSource();
1730 implicitRules().set_isImplicitNoneType(true);
1731 if (prevImplicit_) {
1732 Say("IMPLICIT NONE(TYPE) after IMPLICIT statement"_err_en_US);
1740 Say("TYPE specified more than once in IMPLICIT NONE statement"_err_en_US);
1743 if (sawExternal > 1) {
1744 Say("EXTERNAL specified more than once in IMPLICIT NONE statement"_err_en_US);
1751 // ArraySpecVisitor implementation
1753 void ArraySpecVisitor::Post(const parser::ArraySpec &x) {
1754 CHECK(arraySpec_.empty());
1755 arraySpec_ = AnalyzeArraySpec(context(), x);
1757 void ArraySpecVisitor::Post(const parser::ComponentArraySpec &x) {
1758 CHECK(arraySpec_.empty());
1759 arraySpec_ = AnalyzeArraySpec(context(), x);
1761 void ArraySpecVisitor::Post(const parser::CoarraySpec &x) {
1762 CHECK(coarraySpec_.empty());
1763 coarraySpec_ = AnalyzeCoarraySpec(context(), x);
1766 const ArraySpec &ArraySpecVisitor::arraySpec() {
1767 return !arraySpec_.empty() ? arraySpec_ : attrArraySpec_;
1769 const ArraySpec &ArraySpecVisitor::coarraySpec() {
1770 return !coarraySpec_.empty() ? coarraySpec_ : attrCoarraySpec_;
1772 void ArraySpecVisitor::BeginArraySpec() {
1773 CHECK(arraySpec_.empty());
1774 CHECK(coarraySpec_.empty());
1775 CHECK(attrArraySpec_.empty());
1776 CHECK(attrCoarraySpec_.empty());
1778 void ArraySpecVisitor::EndArraySpec() {
1779 CHECK(arraySpec_.empty());
1780 CHECK(coarraySpec_.empty());
1781 attrArraySpec_.clear();
1782 attrCoarraySpec_.clear();
1784 void ArraySpecVisitor::PostAttrSpec() {
1785 // Save dimension/codimension from attrs so we can process array/coarray-spec
1786 // on the entity-decl
1787 if (!arraySpec_.empty()) {
1788 CHECK(attrArraySpec_.empty());
1789 attrArraySpec_ = arraySpec_;
1792 if (!coarraySpec_.empty()) {
1793 CHECK(attrCoarraySpec_.empty());
1794 attrCoarraySpec_ = coarraySpec_;
1795 coarraySpec_.clear();
1799 // ScopeHandler implementation
1801 void ScopeHandler::SayAlreadyDeclared(const parser::Name &name, Symbol &prev) {
1802 SayAlreadyDeclared(name.source, prev);
1804 void ScopeHandler::SayAlreadyDeclared(const SourceName &name, Symbol &prev) {
1805 if (context().HasError(prev)) {
1806 // don't report another error about prev
1807 } else if (const auto *details{prev.detailsIf<UseDetails>()}) {
1808 Say(name, "'%s' is already declared in this scoping unit"_err_en_US)
1809 .Attach(details->location(),
1810 "It is use-associated with '%s' in module '%s'"_err_en_US,
1811 details->symbol().name(), details->module().name());
1813 SayAlreadyDeclared(name, prev.name());
1815 context().SetError(prev);
1817 void ScopeHandler::SayAlreadyDeclared(
1818 const SourceName &name1, const SourceName &name2) {
1819 if (name1.begin() < name2.begin()) {
1820 SayAlreadyDeclared(name2, name1);
1822 Say(name1, "'%s' is already declared in this scoping unit"_err_en_US)
1823 .Attach(name2, "Previous declaration of '%s'"_en_US, name2);
1827 void ScopeHandler::SayWithReason(const parser::Name &name, Symbol &symbol,
1828 MessageFixedText &&msg1, MessageFixedText &&msg2) {
1829 Say2(name, std::move(msg1), symbol, std::move(msg2));
1830 context().SetError(symbol, msg1.isFatal());
1833 void ScopeHandler::SayWithDecl(
1834 const parser::Name &name, Symbol &symbol, MessageFixedText &&msg) {
1835 SayWithReason(name, symbol, std::move(msg),
1836 symbol.test(Symbol::Flag::Implicit) ? "Implicit declaration of '%s'"_en_US
1837 : "Declaration of '%s'"_en_US);
1840 void ScopeHandler::SayLocalMustBeVariable(
1841 const parser::Name &name, Symbol &symbol) {
1842 SayWithDecl(name, symbol,
1843 "The name '%s' must be a variable to appear"
1844 " in a locality-spec"_err_en_US);
1847 void ScopeHandler::SayDerivedType(
1848 const SourceName &name, MessageFixedText &&msg, const Scope &type) {
1849 const Symbol &typeSymbol{DEREF(type.GetSymbol())};
1850 Say(name, std::move(msg), name, typeSymbol.name())
1851 .Attach(typeSymbol.name(), "Declaration of derived type '%s'"_en_US,
1854 void ScopeHandler::Say2(const SourceName &name1, MessageFixedText &&msg1,
1855 const SourceName &name2, MessageFixedText &&msg2) {
1856 Say(name1, std::move(msg1)).Attach(name2, std::move(msg2), name2);
1858 void ScopeHandler::Say2(const SourceName &name, MessageFixedText &&msg1,
1859 Symbol &symbol, MessageFixedText &&msg2) {
1860 Say2(name, std::move(msg1), symbol.name(), std::move(msg2));
1861 context().SetError(symbol, msg1.isFatal());
1863 void ScopeHandler::Say2(const parser::Name &name, MessageFixedText &&msg1,
1864 Symbol &symbol, MessageFixedText &&msg2) {
1865 Say2(name.source, std::move(msg1), symbol.name(), std::move(msg2));
1866 context().SetError(symbol, msg1.isFatal());
1869 Scope &ScopeHandler::InclusiveScope() {
1870 for (auto *scope{&currScope()};; scope = &scope->parent()) {
1871 if (scope->kind() != Scope::Kind::Block && !scope->IsDerivedType()) {
1875 common::die("inclusive scope not found");
1877 Scope &ScopeHandler::GlobalScope() {
1878 for (auto *scope = currScope_; scope; scope = &scope->parent()) {
1879 if (scope->IsGlobal()) {
1883 common::die("global scope not found");
1885 void ScopeHandler::PushScope(Scope::Kind kind, Symbol *symbol) {
1886 PushScope(currScope().MakeScope(kind, symbol));
1888 void ScopeHandler::PushScope(Scope &scope) {
1889 currScope_ = &scope;
1890 auto kind{currScope_->kind()};
1891 if (kind != Scope::Kind::Block) {
1892 ImplicitRulesVisitor::BeginScope(scope);
1894 // The name of a module or submodule cannot be "used" in its scope,
1895 // as we read 19.3.1(2), so we allow the name to be used as a local
1896 // identifier in the module or submodule too. Same with programs
1897 // (14.1(3)) and BLOCK DATA.
1898 if (!currScope_->IsDerivedType() && kind != Scope::Kind::Module &&
1899 kind != Scope::Kind::MainProgram && kind != Scope::Kind::BlockData) {
1900 if (auto *symbol{scope.symbol()}) {
1901 // Create a dummy symbol so we can't create another one with the same
1902 // name. It might already be there if we previously pushed the scope.
1903 if (!FindInScope(scope, symbol->name())) {
1904 auto &newSymbol{MakeSymbol(symbol->name())};
1905 if (kind == Scope::Kind::Subprogram) {
1906 // Allow for recursive references. If this symbol is a function
1907 // without an explicit RESULT(), this new symbol will be discarded
1908 // and replaced with an object of the same name.
1909 newSymbol.set_details(HostAssocDetails{*symbol});
1911 newSymbol.set_details(MiscDetails{MiscDetails::Kind::ScopeName});
1917 void ScopeHandler::PopScope() {
1918 // Entities that are not yet classified as objects or procedures are now
1919 // assumed to be objects.
1920 // TODO: Statement functions
1921 for (auto &pair : currScope()) {
1922 ConvertToObjectEntity(*pair.second);
1924 SetScope(currScope_->parent());
1926 void ScopeHandler::SetScope(Scope &scope) {
1927 currScope_ = &scope;
1928 ImplicitRulesVisitor::SetScope(InclusiveScope());
1931 Symbol *ScopeHandler::FindSymbol(const parser::Name &name) {
1932 return FindSymbol(currScope(), name);
1934 Symbol *ScopeHandler::FindSymbol(const Scope &scope, const parser::Name &name) {
1935 if (scope.IsDerivedType()) {
1936 if (Symbol * symbol{scope.FindComponent(name.source)}) {
1937 if (!symbol->has<ProcBindingDetails>() &&
1938 !symbol->test(Symbol::Flag::ParentComp)) {
1939 return Resolve(name, symbol);
1942 return FindSymbol(scope.parent(), name);
1944 return Resolve(name, scope.FindSymbol(name.source));
1948 Symbol &ScopeHandler::MakeSymbol(
1949 Scope &scope, const SourceName &name, Attrs attrs) {
1950 if (Symbol * symbol{FindInScope(scope, name)}) {
1951 symbol->attrs() |= attrs;
1954 const auto pair{scope.try_emplace(name, attrs, UnknownDetails{})};
1955 CHECK(pair.second); // name was not found, so must be able to add
1956 return *pair.first->second;
1959 Symbol &ScopeHandler::MakeSymbol(const SourceName &name, Attrs attrs) {
1960 return MakeSymbol(currScope(), name, attrs);
1962 Symbol &ScopeHandler::MakeSymbol(const parser::Name &name, Attrs attrs) {
1963 return Resolve(name, MakeSymbol(name.source, attrs));
1965 Symbol &ScopeHandler::CopySymbol(const SourceName &name, const Symbol &symbol) {
1966 CHECK(!FindInScope(currScope(), name));
1967 return MakeSymbol(currScope(), name, symbol.attrs());
1970 // Look for name only in scope, not in enclosing scopes.
1971 Symbol *ScopeHandler::FindInScope(
1972 const Scope &scope, const parser::Name &name) {
1973 return Resolve(name, FindInScope(scope, name.source));
1975 Symbol *ScopeHandler::FindInScope(const Scope &scope, const SourceName &name) {
1976 if (auto it{scope.find(name)}; it != scope.end()) {
1977 return &*it->second;
1983 // Find a component or type parameter by name in a derived type or its parents.
1984 Symbol *ScopeHandler::FindInTypeOrParents(
1985 const Scope &scope, const parser::Name &name) {
1986 return Resolve(name, scope.FindComponent(name.source));
1988 Symbol *ScopeHandler::FindInTypeOrParents(const parser::Name &name) {
1989 return FindInTypeOrParents(currScope(), name);
1992 void ScopeHandler::EraseSymbol(const parser::Name &name) {
1993 currScope().erase(name.source);
1994 name.symbol = nullptr;
1997 static bool NeedsType(const Symbol &symbol) {
1998 return !symbol.GetType() &&
2001 [](const EntityDetails &) { return true; },
2002 [](const ObjectEntityDetails &) { return true; },
2003 [](const AssocEntityDetails &) { return true; },
2004 [&](const ProcEntityDetails &p) {
2005 return symbol.test(Symbol::Flag::Function) &&
2006 !symbol.attrs().test(Attr::INTRINSIC) &&
2007 !p.interface().type() && !p.interface().symbol();
2009 [](const auto &) { return false; },
2013 void ScopeHandler::ApplyImplicitRules(Symbol &symbol) {
2014 if (NeedsType(symbol)) {
2015 if (const DeclTypeSpec * type{GetImplicitType(symbol)}) {
2016 symbol.set(Symbol::Flag::Implicit);
2017 symbol.SetType(*type);
2018 } else if (symbol.has<ProcEntityDetails>() &&
2019 !symbol.attrs().test(Attr::EXTERNAL) &&
2020 context().intrinsics().IsIntrinsic(symbol.name().ToString())) {
2021 // type will be determined in expression semantics
2022 symbol.attrs().set(Attr::INTRINSIC);
2023 } else if (!context().HasError(symbol)) {
2024 Say(symbol.name(), "No explicit type declared for '%s'"_err_en_US);
2025 context().SetError(symbol);
2029 const DeclTypeSpec *ScopeHandler::GetImplicitType(Symbol &symbol) {
2030 const DeclTypeSpec *type{implicitRules().GetType(symbol.name().begin()[0])};
2032 if (const DerivedTypeSpec * derived{type->AsDerived()}) {
2033 // Resolve any forward-referenced derived type; a quick no-op else.
2034 auto &instantiatable{*const_cast<DerivedTypeSpec *>(derived)};
2035 instantiatable.Instantiate(currScope(), context());
2041 // Convert symbol to be a ObjectEntity or return false if it can't be.
2042 bool ScopeHandler::ConvertToObjectEntity(Symbol &symbol) {
2043 if (symbol.has<ObjectEntityDetails>()) {
2045 } else if (symbol.has<UnknownDetails>()) {
2046 symbol.set_details(ObjectEntityDetails{});
2047 } else if (auto *details{symbol.detailsIf<EntityDetails>()}) {
2048 symbol.set_details(ObjectEntityDetails{std::move(*details)});
2049 } else if (auto *useDetails{symbol.detailsIf<UseDetails>()}) {
2050 return useDetails->symbol().has<ObjectEntityDetails>();
2056 // Convert symbol to be a ProcEntity or return false if it can't be.
2057 bool ScopeHandler::ConvertToProcEntity(Symbol &symbol) {
2058 if (symbol.has<ProcEntityDetails>()) {
2060 } else if (symbol.has<UnknownDetails>()) {
2061 symbol.set_details(ProcEntityDetails{});
2062 } else if (auto *details{symbol.detailsIf<EntityDetails>()}) {
2063 symbol.set_details(ProcEntityDetails{std::move(*details)});
2064 if (symbol.GetType() && !symbol.test(Symbol::Flag::Implicit)) {
2065 CHECK(!symbol.test(Symbol::Flag::Subroutine));
2066 symbol.set(Symbol::Flag::Function);
2074 const DeclTypeSpec &ScopeHandler::MakeNumericType(
2075 TypeCategory category, const std::optional<parser::KindSelector> &kind) {
2076 KindExpr value{GetKindParamExpr(category, kind)};
2077 if (auto known{evaluate::ToInt64(value)}) {
2078 return context().MakeNumericType(category, static_cast<int>(*known));
2080 return currScope_->MakeNumericType(category, std::move(value));
2084 const DeclTypeSpec &ScopeHandler::MakeLogicalType(
2085 const std::optional<parser::KindSelector> &kind) {
2086 KindExpr value{GetKindParamExpr(TypeCategory::Logical, kind)};
2087 if (auto known{evaluate::ToInt64(value)}) {
2088 return context().MakeLogicalType(static_cast<int>(*known));
2090 return currScope_->MakeLogicalType(std::move(value));
2094 void ScopeHandler::MakeExternal(Symbol &symbol) {
2095 if (!symbol.attrs().test(Attr::EXTERNAL)) {
2096 symbol.attrs().set(Attr::EXTERNAL);
2097 if (symbol.attrs().test(Attr::INTRINSIC)) { // C840
2099 "Symbol '%s' cannot have both EXTERNAL and INTRINSIC attributes"_err_en_US,
2105 // ModuleVisitor implementation
2107 bool ModuleVisitor::Pre(const parser::Only &x) {
2110 [&](const Indirection<parser::GenericSpec> &generic) {
2111 AddUse(GenericSpecInfo{generic.value()});
2113 [&](const parser::Name &name) {
2114 Resolve(name, AddUse(name.source, name.source).use);
2116 [&](const parser::Rename &rename) { Walk(rename); },
2122 bool ModuleVisitor::Pre(const parser::Rename::Names &x) {
2123 const auto &localName{std::get<0>(x.t)};
2124 const auto &useName{std::get<1>(x.t)};
2125 SymbolRename rename{AddUse(localName.source, useName.source)};
2126 Resolve(useName, rename.use);
2127 Resolve(localName, rename.local);
2130 bool ModuleVisitor::Pre(const parser::Rename::Operators &x) {
2131 const parser::DefinedOpName &local{std::get<0>(x.t)};
2132 const parser::DefinedOpName &use{std::get<1>(x.t)};
2133 GenericSpecInfo localInfo{local};
2134 GenericSpecInfo useInfo{use};
2135 if (IsIntrinsicOperator(context(), local.v.source)) {
2137 "Intrinsic operator '%s' may not be used as a defined operator"_err_en_US);
2138 } else if (IsLogicalConstant(context(), local.v.source)) {
2140 "Logical constant '%s' may not be used as a defined operator"_err_en_US);
2142 SymbolRename rename{AddUse(localInfo.symbolName(), useInfo.symbolName())};
2143 useInfo.Resolve(rename.use);
2144 localInfo.Resolve(rename.local);
2149 // Set useModuleScope_ to the Scope of the module being used.
2150 bool ModuleVisitor::Pre(const parser::UseStmt &x) {
2151 useModuleScope_ = FindModule(x.moduleName);
2152 return useModuleScope_ != nullptr;
2154 void ModuleVisitor::Post(const parser::UseStmt &x) {
2155 if (const auto *list{std::get_if<std::list<parser::Rename>>(&x.u)}) {
2156 // Not a use-only: collect the names that were used in renames,
2157 // then add a use for each public name that was not renamed.
2158 std::set<SourceName> useNames;
2159 for (const auto &rename : *list) {
2162 [&](const parser::Rename::Names &names) {
2163 useNames.insert(std::get<1>(names.t).source);
2165 [&](const parser::Rename::Operators &ops) {
2166 useNames.insert(std::get<1>(ops.t).v.source);
2171 for (const auto &[name, symbol] : *useModuleScope_) {
2172 if (symbol->attrs().test(Attr::PUBLIC) &&
2173 !symbol->detailsIf<MiscDetails>()) {
2174 if (useNames.count(name) == 0) {
2175 auto *localSymbol{FindInScope(currScope(), name)};
2177 localSymbol = &CopySymbol(name, *symbol);
2179 AddUse(x.moduleName.source, *localSymbol, *symbol);
2184 useModuleScope_ = nullptr;
2187 ModuleVisitor::SymbolRename ModuleVisitor::AddUse(
2188 const SourceName &localName, const SourceName &useName) {
2189 return AddUse(localName, useName, FindInScope(*useModuleScope_, useName));
2192 ModuleVisitor::SymbolRename ModuleVisitor::AddUse(
2193 const SourceName &localName, const SourceName &useName, Symbol *useSymbol) {
2194 if (!useModuleScope_) {
2195 return {}; // error occurred finding module
2199 IsDefinedOperator(useName)
2200 ? "Operator '%s' not found in module '%s'"_err_en_US
2201 : "'%s' not found in module '%s'"_err_en_US,
2202 useName, useModuleScope_->GetName().value());
2205 if (useSymbol->attrs().test(Attr::PRIVATE)) {
2207 IsDefinedOperator(useName)
2208 ? "Operator '%s' is PRIVATE in '%s'"_err_en_US
2209 : "'%s' is PRIVATE in '%s'"_err_en_US,
2210 useName, useModuleScope_->GetName().value());
2213 auto &localSymbol{MakeSymbol(localName)};
2214 AddUse(useName, localSymbol, *useSymbol);
2215 return {&localSymbol, useSymbol};
2218 // symbol must be either a Use or a Generic formed by merging two uses.
2219 // Convert it to a UseError with this additional location.
2220 static void ConvertToUseError(
2221 Symbol &symbol, const SourceName &location, const Scope &module) {
2222 const auto *useDetails{symbol.detailsIf<UseDetails>()};
2224 auto &genericDetails{symbol.get<GenericDetails>()};
2225 useDetails = &genericDetails.useDetails().value();
2228 UseErrorDetails{*useDetails}.add_occurrence(location, module));
2231 void ModuleVisitor::AddUse(
2232 const SourceName &location, Symbol &localSymbol, const Symbol &useSymbol) {
2233 localSymbol.attrs() = useSymbol.attrs() & ~Attrs{Attr::PUBLIC, Attr::PRIVATE};
2234 localSymbol.flags() = useSymbol.flags();
2235 if (auto *useDetails{localSymbol.detailsIf<UseDetails>()}) {
2236 const Symbol &ultimate{localSymbol.GetUltimate()};
2237 if (ultimate == useSymbol.GetUltimate()) {
2238 // use-associating the same symbol again -- ok
2239 } else if (ultimate.has<GenericDetails>() &&
2240 useSymbol.has<GenericDetails>()) {
2241 // use-associating generics with the same names: merge them into a
2242 // new generic in this scope
2243 auto generic1{ultimate.get<GenericDetails>()};
2244 generic1.set_useDetails(*useDetails);
2245 // useSymbol has specific g and so does generic1
2246 auto &generic2{useSymbol.get<GenericDetails>()};
2247 if (generic1.specific() && generic2.specific() &&
2248 generic1.specific() != generic2.specific()) {
2250 "Generic interface '%s' has ambiguous specific procedures"
2251 " from modules '%s' and '%s'"_err_en_US,
2252 localSymbol.name(), useDetails->module().name(),
2253 useSymbol.owner().GetName().value());
2254 } else if (generic1.derivedType() && generic2.derivedType() &&
2255 generic1.derivedType() != generic2.derivedType()) {
2257 "Generic interface '%s' has ambiguous derived types"
2258 " from modules '%s' and '%s'"_err_en_US,
2259 localSymbol.name(), useDetails->module().name(),
2260 useSymbol.owner().GetName().value());
2262 generic1.CopyFrom(generic2);
2264 EraseSymbol(localSymbol);
2265 MakeSymbol(localSymbol.name(), ultimate.attrs(), std::move(generic1));
2267 ConvertToUseError(localSymbol, location, *useModuleScope_);
2270 auto *genericDetails{localSymbol.detailsIf<GenericDetails>()};
2271 if (genericDetails && genericDetails->useDetails()) {
2272 // localSymbol came from merging two use-associated generics
2273 if (auto *useDetails{useSymbol.detailsIf<GenericDetails>()}) {
2274 genericDetails->CopyFrom(*useDetails);
2276 ConvertToUseError(localSymbol, location, *useModuleScope_);
2278 } else if (auto *details{localSymbol.detailsIf<UseErrorDetails>()}) {
2279 details->add_occurrence(location, *useModuleScope_);
2280 } else if (!localSymbol.has<UnknownDetails>()) {
2282 "Cannot use-associate '%s'; it is already declared in this scope"_err_en_US,
2284 .Attach(localSymbol.name(), "Previous declaration of '%s'"_en_US,
2285 localSymbol.name());
2287 localSymbol.set_details(UseDetails{location, useSymbol});
2292 void ModuleVisitor::AddUse(const GenericSpecInfo &info) {
2293 if (useModuleScope_) {
2294 const auto &name{info.symbolName()};
2296 AddUse(name, name, info.FindInScope(context(), *useModuleScope_))};
2297 info.Resolve(rename.use);
2301 bool ModuleVisitor::BeginSubmodule(
2302 const parser::Name &name, const parser::ParentIdentifier &parentId) {
2303 auto &ancestorName{std::get<parser::Name>(parentId.t)};
2304 auto &parentName{std::get<std::optional<parser::Name>>(parentId.t)};
2305 Scope *ancestor{FindModule(ancestorName)};
2309 Scope *parentScope{parentName ? FindModule(*parentName, ancestor) : ancestor};
2313 PushScope(*parentScope); // submodule is hosted in parent
2314 BeginModule(name, true);
2315 if (!ancestor->AddSubmodule(name.source, currScope())) {
2316 Say(name, "Module '%s' already has a submodule named '%s'"_err_en_US,
2317 ancestorName.source, name.source);
2322 void ModuleVisitor::BeginModule(const parser::Name &name, bool isSubmodule) {
2323 auto &symbol{MakeSymbol(name, ModuleDetails{isSubmodule})};
2324 auto &details{symbol.get<ModuleDetails>()};
2325 PushScope(Scope::Kind::Module, &symbol);
2326 details.set_scope(&currScope());
2327 defaultAccess_ = Attr::PUBLIC;
2328 prevAccessStmt_ = std::nullopt;
2331 // Find a module or submodule by name and return its scope.
2332 // If ancestor is present, look for a submodule of that ancestor module.
2333 // May have to read a .mod file to find it.
2334 // If an error occurs, report it and return nullptr.
2335 Scope *ModuleVisitor::FindModule(const parser::Name &name, Scope *ancestor) {
2336 ModFileReader reader{context()};
2337 Scope *scope{reader.Read(name.source, ancestor)};
2341 if (scope->kind() != Scope::Kind::Module) {
2342 Say(name, "'%s' is not a module"_err_en_US);
2345 if (DoesScopeContain(scope, currScope())) { // 14.2.2(1)
2346 Say(name, "Module '%s' cannot USE itself"_err_en_US);
2348 Resolve(name, scope->symbol());
2352 void ModuleVisitor::ApplyDefaultAccess() {
2353 for (auto &pair : currScope()) {
2354 Symbol &symbol = *pair.second;
2355 if (!symbol.attrs().HasAny({Attr::PUBLIC, Attr::PRIVATE})) {
2356 symbol.attrs().set(defaultAccess_);
2361 // InterfaceVistor implementation
2363 bool InterfaceVisitor::Pre(const parser::InterfaceStmt &x) {
2364 bool isAbstract{std::holds_alternative<parser::Abstract>(x.u)};
2365 genericInfo_.emplace(/*isInterface*/ true, isAbstract);
2369 void InterfaceVisitor::Post(const parser::EndInterfaceStmt &) {
2373 // Create a symbol in genericSymbol_ for this GenericSpec.
2374 bool InterfaceVisitor::Pre(const parser::GenericSpec &x) {
2375 if (auto *symbol{GenericSpecInfo{x}.FindInScope(context(), currScope())}) {
2376 SetGenericSymbol(*symbol);
2381 bool InterfaceVisitor::Pre(const parser::ProcedureStmt &x) {
2383 Say("A PROCEDURE statement is only allowed in a generic interface block"_err_en_US);
2386 auto kind{std::get<parser::ProcedureStmt::Kind>(x.t)};
2387 const auto &names{std::get<std::list<parser::Name>>(x.t)};
2388 AddSpecificProcs(names, kind);
2392 bool InterfaceVisitor::Pre(const parser::GenericStmt &) {
2393 genericInfo_.emplace(/*isInterface*/ false);
2396 void InterfaceVisitor::Post(const parser::GenericStmt &x) {
2397 if (auto &accessSpec{std::get<std::optional<parser::AccessSpec>>(x.t)}) {
2398 GetGenericInfo().symbol->attrs().set(AccessSpecToAttr(*accessSpec));
2400 const auto &names{std::get<std::list<parser::Name>>(x.t)};
2401 AddSpecificProcs(names, ProcedureKind::Procedure);
2405 bool InterfaceVisitor::inInterfaceBlock() const {
2406 return !genericInfo_.empty() && GetGenericInfo().isInterface;
2408 bool InterfaceVisitor::isGeneric() const {
2409 return !genericInfo_.empty() && GetGenericInfo().symbol;
2411 bool InterfaceVisitor::isAbstract() const {
2412 return !genericInfo_.empty() && GetGenericInfo().isAbstract;
2414 GenericDetails &InterfaceVisitor::GetGenericDetails() {
2415 return GetGenericInfo().symbol->get<GenericDetails>();
2418 void InterfaceVisitor::AddSpecificProcs(
2419 const std::list<parser::Name> &names, ProcedureKind kind) {
2420 for (const auto &name : names) {
2421 specificProcs_.emplace(
2422 GetGenericInfo().symbol, std::make_pair(&name, kind));
2426 // By now we should have seen all specific procedures referenced by name in
2427 // this generic interface. Resolve those names to symbols.
2428 void InterfaceVisitor::ResolveSpecificsInGeneric(Symbol &generic) {
2429 auto &details{generic.get<GenericDetails>()};
2430 std::set<SourceName> namesSeen; // to check for duplicate names
2431 for (const Symbol &symbol : details.specificProcs()) {
2432 namesSeen.insert(symbol.name());
2434 auto range{specificProcs_.equal_range(&generic)};
2435 for (auto it{range.first}; it != range.second; ++it) {
2436 auto *name{it->second.first};
2437 auto kind{it->second.second};
2438 const auto *symbol{FindSymbol(*name)};
2440 Say(*name, "Procedure '%s' not found"_err_en_US);
2443 symbol = &symbol->GetUltimate();
2444 if (symbol == &generic) {
2445 if (auto *specific{generic.get<GenericDetails>().specific()}) {
2449 if (!symbol->has<SubprogramDetails>() &&
2450 !symbol->has<SubprogramNameDetails>()) {
2451 Say(*name, "'%s' is not a subprogram"_err_en_US);
2454 if (kind == ProcedureKind::ModuleProcedure) {
2455 if (const auto *nd{symbol->detailsIf<SubprogramNameDetails>()}) {
2456 if (nd->kind() != SubprogramKind::Module) {
2457 Say(*name, "'%s' is not a module procedure"_err_en_US);
2460 // USE-associated procedure
2461 const auto *sd{symbol->detailsIf<SubprogramDetails>()};
2463 if (symbol->owner().kind() != Scope::Kind::Module ||
2464 sd->isInterface()) {
2465 Say(*name, "'%s' is not a module procedure"_err_en_US);
2469 if (!namesSeen.insert(name->source).second) {
2471 details.kind().IsDefinedOperator()
2472 ? "Procedure '%s' is already specified in generic operator '%s'"_err_en_US
2473 : "Procedure '%s' is already specified in generic '%s'"_err_en_US,
2474 name->source, generic.name());
2477 details.AddSpecificProc(*symbol, name->source);
2479 specificProcs_.erase(range.first, range.second);
2482 // Check that the specific procedures are all functions or all subroutines.
2483 // If there is a derived type with the same name they must be functions.
2484 // Set the corresponding flag on generic.
2485 void InterfaceVisitor::CheckGenericProcedures(Symbol &generic) {
2486 ResolveSpecificsInGeneric(generic);
2487 auto &details{generic.get<GenericDetails>()};
2488 if (auto *proc{details.CheckSpecific()}) {
2490 "'%s' may not be the name of both a generic interface and a"
2491 " procedure unless it is a specific procedure of the generic"_err_en_US};
2492 if (proc->name().begin() > generic.name().begin()) {
2493 Say(proc->name(), std::move(msg));
2495 Say(generic.name(), std::move(msg));
2498 auto &specifics{details.specificProcs()};
2499 if (specifics.empty()) {
2500 if (details.derivedType()) {
2501 generic.set(Symbol::Flag::Function);
2505 const Symbol &firstSpecific{specifics.front()};
2506 bool isFunction{firstSpecific.test(Symbol::Flag::Function)};
2507 for (const Symbol &specific : specifics) {
2508 if (isFunction != specific.test(Symbol::Flag::Function)) { // C1514
2509 auto &msg{Say(generic.name(),
2510 "Generic interface '%s' has both a function and a subroutine"_err_en_US)};
2512 msg.Attach(firstSpecific.name(), "Function declaration"_en_US);
2513 msg.Attach(specific.name(), "Subroutine declaration"_en_US);
2515 msg.Attach(firstSpecific.name(), "Subroutine declaration"_en_US);
2516 msg.Attach(specific.name(), "Function declaration"_en_US);
2520 if (!isFunction && details.derivedType()) {
2521 SayDerivedType(generic.name(),
2522 "Generic interface '%s' may only contain functions due to derived type"
2523 " with same name"_err_en_US,
2524 *details.derivedType()->scope());
2526 generic.set(isFunction ? Symbol::Flag::Function : Symbol::Flag::Subroutine);
2529 // SubprogramVisitor implementation
2531 // Return false if it is actually an assignment statement.
2532 bool SubprogramVisitor::HandleStmtFunction(const parser::StmtFunctionStmt &x) {
2533 const auto &name{std::get<parser::Name>(x.t)};
2534 const DeclTypeSpec *resultType{nullptr};
2535 // Look up name: provides return type or tells us if it's an array
2536 if (auto *symbol{FindSymbol(name)}) {
2537 auto *details{symbol->detailsIf<EntityDetails>()};
2539 badStmtFuncFound_ = true;
2542 // TODO: check that attrs are compatible with stmt func
2543 resultType = details->type();
2544 symbol->details() = UnknownDetails{}; // will be replaced below
2546 if (badStmtFuncFound_) {
2547 Say(name, "'%s' has not been declared as an array"_err_en_US);
2550 auto &symbol{PushSubprogramScope(name, Symbol::Flag::Function)};
2551 EraseSymbol(symbol); // removes symbol added by PushSubprogramScope
2552 auto &details{symbol.get<SubprogramDetails>()};
2553 for (const auto &dummyName : std::get<std::list<parser::Name>>(x.t)) {
2554 ObjectEntityDetails dummyDetails{true};
2555 if (auto *dummySymbol{FindInScope(currScope().parent(), dummyName)}) {
2556 if (auto *d{dummySymbol->detailsIf<EntityDetails>()}) {
2558 dummyDetails.set_type(*d->type());
2562 Symbol &dummy{MakeSymbol(dummyName, std::move(dummyDetails))};
2563 ApplyImplicitRules(dummy);
2564 details.add_dummyArg(dummy);
2566 ObjectEntityDetails resultDetails;
2568 resultDetails.set_type(*resultType);
2570 Symbol &result{MakeSymbol(name, std::move(resultDetails))};
2571 ApplyImplicitRules(result);
2572 details.set_result(result);
2573 const auto &parsedExpr{std::get<parser::Scalar<parser::Expr>>(x.t)};
2575 if (auto expr{AnalyzeExpr(context(), parsedExpr)}) {
2576 details.set_stmtFunction(std::move(*expr));
2578 context().SetError(symbol);
2584 bool SubprogramVisitor::Pre(const parser::Suffix &suffix) {
2585 if (suffix.resultName) {
2586 funcInfo_.resultName = &suffix.resultName.value();
2591 bool SubprogramVisitor::Pre(const parser::PrefixSpec &x) {
2592 // Save this to process after UseStmt and ImplicitPart
2593 if (const auto *parsedType{std::get_if<parser::DeclarationTypeSpec>(&x.u)}) {
2594 funcInfo_.parsedType = parsedType;
2595 funcInfo_.source = currStmtSource();
2602 void SubprogramVisitor::Post(const parser::ImplicitPart &) {
2603 // If the function has a type in the prefix, process it now
2604 if (funcInfo_.parsedType) {
2605 messageHandler().set_currStmtSource(funcInfo_.source);
2606 if (const auto *type{ProcessTypeSpec(*funcInfo_.parsedType, true)}) {
2607 funcInfo_.resultSymbol->SetType(*type);
2613 bool SubprogramVisitor::Pre(const parser::InterfaceBody::Subroutine &x) {
2614 const auto &name{std::get<parser::Name>(
2615 std::get<parser::Statement<parser::SubroutineStmt>>(x.t).statement.t)};
2616 return BeginSubprogram(name, Symbol::Flag::Subroutine);
2618 void SubprogramVisitor::Post(const parser::InterfaceBody::Subroutine &) {
2621 bool SubprogramVisitor::Pre(const parser::InterfaceBody::Function &x) {
2622 const auto &name{std::get<parser::Name>(
2623 std::get<parser::Statement<parser::FunctionStmt>>(x.t).statement.t)};
2624 return BeginSubprogram(name, Symbol::Flag::Function);
2626 void SubprogramVisitor::Post(const parser::InterfaceBody::Function &) {
2630 bool SubprogramVisitor::Pre(const parser::SubroutineStmt &) {
2631 return BeginAttrs();
2633 bool SubprogramVisitor::Pre(const parser::FunctionStmt &) {
2634 return BeginAttrs();
2637 void SubprogramVisitor::Post(const parser::SubroutineStmt &stmt) {
2638 const auto &name{std::get<parser::Name>(stmt.t)};
2639 auto &details{PostSubprogramStmt(name)};
2640 for (const auto &dummyArg : std::get<std::list<parser::DummyArg>>(stmt.t)) {
2641 if (const auto *dummyName{std::get_if<parser::Name>(&dummyArg.u)}) {
2642 Symbol &dummy{MakeSymbol(*dummyName, EntityDetails(true))};
2643 details.add_dummyArg(dummy);
2645 details.add_alternateReturn();
2650 void SubprogramVisitor::Post(const parser::FunctionStmt &stmt) {
2651 const auto &name{std::get<parser::Name>(stmt.t)};
2652 auto &details{PostSubprogramStmt(name)};
2653 for (const auto &dummyName : std::get<std::list<parser::Name>>(stmt.t)) {
2654 Symbol &dummy{MakeSymbol(dummyName, EntityDetails(true))};
2655 details.add_dummyArg(dummy);
2657 const parser::Name *funcResultName;
2658 if (funcInfo_.resultName && funcInfo_.resultName->source != name.source) {
2659 // Note that RESULT is ignored if it has the same name as the function.
2660 funcResultName = funcInfo_.resultName;
2662 EraseSymbol(name); // was added by PushSubprogramScope
2663 funcResultName = &name;
2665 // add function result to function scope
2666 EntityDetails funcResultDetails;
2667 funcResultDetails.set_funcResult(true);
2668 funcInfo_.resultSymbol =
2669 &MakeSymbol(*funcResultName, std::move(funcResultDetails));
2670 details.set_result(*funcInfo_.resultSymbol);
2672 // C1560. TODO also enforce on entry names when entry implemented
2673 if (funcInfo_.resultName && funcInfo_.resultName->source == name.source) {
2674 Say(funcInfo_.resultName->source,
2675 "The function name should not appear in RESULT, references to '%s' "
2677 " the function will be considered as references to the result only"_en_US,
2679 // RESULT name was ignored above, the only side effect from doing so will be
2680 // the inability to make recursive calls. The related parser::Name is still
2681 // resolved to the created function result symbol because every parser::Name
2682 // should be resolved to avoid internal errors.
2683 Resolve(*funcInfo_.resultName, funcInfo_.resultSymbol);
2685 name.symbol = currScope().symbol(); // must not be function result symbol
2688 SubprogramDetails &SubprogramVisitor::PostSubprogramStmt(
2689 const parser::Name &name) {
2690 Symbol &symbol{*currScope().symbol()};
2691 CHECK(name.source == symbol.name());
2692 SetBindNameOn(symbol);
2693 symbol.attrs() |= EndAttrs();
2694 if (symbol.attrs().test(Attr::MODULE)) {
2695 symbol.attrs().set(Attr::EXTERNAL, false);
2697 return symbol.get<SubprogramDetails>();
2700 // A subprogram declared with MODULE PROCEDURE
2701 bool SubprogramVisitor::BeginMpSubprogram(const parser::Name &name) {
2702 auto *symbol{FindSymbol(name)};
2703 if (symbol && symbol->has<SubprogramNameDetails>()) {
2704 symbol = FindSymbol(currScope().parent(), name);
2706 if (!symbol || !symbol->IsSeparateModuleProc()) {
2707 Say(name, "'%s' was not declared a separate module procedure"_err_en_US);
2710 if (symbol->owner() != currScope()) {
2711 symbol = &MakeSymbol(name, SubprogramDetails{});
2713 PushScope(Scope::Kind::Subprogram, symbol);
2717 // A subprogram declared with SUBROUTINE or FUNCTION
2718 bool SubprogramVisitor::BeginSubprogram(
2719 const parser::Name &name, Symbol::Flag subpFlag, bool hasModulePrefix) {
2720 if (hasModulePrefix && !inInterfaceBlock()) {
2721 auto *symbol{FindSymbol(currScope().parent(), name)};
2722 if (!symbol || !symbol->IsSeparateModuleProc()) {
2723 Say(name, "'%s' was not declared a separate module procedure"_err_en_US);
2727 PushSubprogramScope(name, subpFlag);
2731 void SubprogramVisitor::EndSubprogram() { PopScope(); }
2733 Symbol &SubprogramVisitor::PushSubprogramScope(
2734 const parser::Name &name, Symbol::Flag subpFlag) {
2735 auto *symbol{GetSpecificFromGeneric(name)};
2737 if (auto *prev{FindSymbol(name)}) {
2738 if (prev->attrs().test(Attr::EXTERNAL) &&
2739 prev->has<ProcEntityDetails>()) {
2740 // this subprogram was previously called, now being declared
2741 if (!prev->test(subpFlag)) {
2743 subpFlag == Symbol::Flag::Function
2744 ? "'%s' was previously called as a subroutine"_err_en_US
2745 : "'%s' was previously called as a function"_err_en_US,
2746 *prev, "Previous call of '%s'"_en_US);
2751 symbol = &MakeSymbol(name, SubprogramDetails{});
2753 symbol->set(subpFlag);
2754 PushScope(Scope::Kind::Subprogram, symbol);
2755 auto &details{symbol->get<SubprogramDetails>()};
2756 if (inInterfaceBlock()) {
2757 details.set_isInterface();
2758 if (!isAbstract()) {
2759 MakeExternal(*symbol);
2762 GetGenericDetails().AddSpecificProc(*symbol, name.source);
2764 implicitRules().set_inheritFromParent(false);
2766 FindSymbol(name)->set(subpFlag); // PushScope() created symbol
2770 void SubprogramVisitor::PushBlockDataScope(const parser::Name &name) {
2771 if (auto *prev{FindSymbol(name)}) {
2772 if (prev->attrs().test(Attr::EXTERNAL) && prev->has<ProcEntityDetails>()) {
2773 if (prev->test(Symbol::Flag::Subroutine) ||
2774 prev->test(Symbol::Flag::Function)) {
2775 Say2(name, "BLOCK DATA '%s' has been called"_err_en_US, *prev,
2776 "Previous call of '%s'"_en_US);
2781 if (name.source.empty()) {
2782 // Don't let unnamed BLOCK DATA conflict with unnamed PROGRAM
2783 PushScope(Scope::Kind::BlockData, nullptr);
2785 PushScope(Scope::Kind::BlockData, &MakeSymbol(name, SubprogramDetails{}));
2789 // If name is a generic, return specific subprogram with the same name.
2790 Symbol *SubprogramVisitor::GetSpecificFromGeneric(const parser::Name &name) {
2791 if (auto *symbol{FindSymbol(name)}) {
2792 if (auto *details{symbol->detailsIf<GenericDetails>()}) {
2793 // found generic, want subprogram
2794 auto *specific{details->specific()};
2797 &currScope().MakeSymbol(name.source, Attrs{}, SubprogramDetails{});
2798 details->set_specific(Resolve(name, *specific));
2799 } else if (isGeneric()) {
2800 SayAlreadyDeclared(name, *specific);
2801 } else if (!specific->has<SubprogramDetails>()) {
2802 specific->set_details(SubprogramDetails{});
2810 // DeclarationVisitor implementation
2812 bool DeclarationVisitor::BeginDecl() {
2813 BeginDeclTypeSpec();
2815 return BeginAttrs();
2817 void DeclarationVisitor::EndDecl() {
2823 bool DeclarationVisitor::CheckUseError(const parser::Name &name) {
2824 const auto *details{name.symbol->detailsIf<UseErrorDetails>()};
2828 Message &msg{Say(name, "Reference to '%s' is ambiguous"_err_en_US)};
2829 for (const auto &[location, module] : details->occurrences()) {
2830 msg.Attach(location, "'%s' was use-associated from module '%s'"_en_US,
2831 name.source, module->GetName().value());
2836 // Report error if accessibility of symbol doesn't match isPrivate.
2837 void DeclarationVisitor::CheckAccessibility(
2838 const SourceName &name, bool isPrivate, Symbol &symbol) {
2839 if (symbol.attrs().test(Attr::PRIVATE) != isPrivate) {
2841 "'%s' does not have the same accessibility as its previous declaration"_err_en_US,
2842 symbol, "Previous declaration of '%s'"_en_US);
2846 // Check that component is accessible from current scope.
2847 bool DeclarationVisitor::CheckAccessibleComponent(
2848 const SourceName &name, const Symbol &symbol) {
2849 if (!symbol.attrs().test(Attr::PRIVATE)) {
2852 // component must be in a module/submodule because of PRIVATE:
2853 const Scope *moduleScope{&symbol.owner()};
2854 CHECK(moduleScope->IsDerivedType());
2856 moduleScope->kind() != Scope::Kind::Module && !moduleScope->IsGlobal()) {
2857 moduleScope = &moduleScope->parent();
2859 if (moduleScope->kind() == Scope::Kind::Module) {
2860 for (auto *scope{&currScope()}; !scope->IsGlobal();
2861 scope = &scope->parent()) {
2862 if (scope == moduleScope) {
2867 "PRIVATE component '%s' is only accessible within module '%s'"_err_en_US,
2868 name.ToString(), moduleScope->GetName().value());
2871 "PRIVATE component '%s' is only accessible within its module"_err_en_US,
2877 void DeclarationVisitor::Post(const parser::DimensionStmt::Declaration &x) {
2878 const auto &name{std::get<parser::Name>(x.t)};
2879 DeclareObjectEntity(name, Attrs{});
2881 void DeclarationVisitor::Post(const parser::CodimensionDecl &x) {
2882 const auto &name{std::get<parser::Name>(x.t)};
2883 DeclareObjectEntity(name, Attrs{});
2886 bool DeclarationVisitor::Pre(const parser::Initialization &) {
2887 // Defer inspection of initializers to Initialization() so that the
2888 // symbol being initialized will be available within the initialization
2893 void DeclarationVisitor::Post(const parser::EntityDecl &x) {
2894 // TODO: may be under StructureStmt
2895 const auto &name{std::get<parser::ObjectName>(x.t)};
2896 Attrs attrs{attrs_ ? HandleSaveName(name.source, *attrs_) : Attrs{}};
2897 Symbol &symbol{DeclareUnknownEntity(name, attrs)};
2898 symbol.ReplaceName(name.source);
2899 if (auto &init{std::get<std::optional<parser::Initialization>>(x.t)}) {
2900 if (ConvertToObjectEntity(symbol)) {
2901 Initialization(name, *init, false);
2903 } else if (attrs.test(Attr::PARAMETER)) {
2904 Say(name, "Missing initialization for parameter '%s'"_err_en_US);
2908 void DeclarationVisitor::Post(const parser::PointerDecl &x) {
2909 const auto &name{std::get<parser::Name>(x.t)};
2910 Symbol &symbol{DeclareUnknownEntity(name, Attrs{Attr::POINTER})};
2911 symbol.ReplaceName(name.source);
2914 bool DeclarationVisitor::Pre(const parser::BindEntity &x) {
2915 auto kind{std::get<parser::BindEntity::Kind>(x.t)};
2916 auto &name{std::get<parser::Name>(x.t)};
2918 if (kind == parser::BindEntity::Kind::Object) {
2919 symbol = &HandleAttributeStmt(Attr::BIND_C, name);
2921 symbol = &MakeCommonBlockSymbol(name);
2922 symbol->attrs().set(Attr::BIND_C);
2924 SetBindNameOn(*symbol);
2927 bool DeclarationVisitor::Pre(const parser::NamedConstantDef &x) {
2928 auto &name{std::get<parser::NamedConstant>(x.t).v};
2929 auto &symbol{HandleAttributeStmt(Attr::PARAMETER, name)};
2930 if (!ConvertToObjectEntity(symbol) ||
2931 symbol.test(Symbol::Flag::CrayPointer) ||
2932 symbol.test(Symbol::Flag::CrayPointee)) {
2934 name, symbol, "PARAMETER attribute not allowed on '%s'"_err_en_US);
2937 const auto &expr{std::get<parser::ConstantExpr>(x.t)};
2938 ApplyImplicitRules(symbol);
2941 EvaluateConvertedExpr(symbol, expr, expr.thing.value().source)}) {
2942 symbol.get<ObjectEntityDetails>().set_init(std::move(*converted));
2946 bool DeclarationVisitor::Pre(const parser::NamedConstant &x) {
2947 const parser::Name &name{x.v};
2948 if (!FindSymbol(name)) {
2949 Say(name, "Named constant '%s' not found"_err_en_US);
2951 CheckUseError(name);
2956 bool DeclarationVisitor::Pre(const parser::Enumerator &enumerator) {
2957 const parser::Name &name{std::get<parser::NamedConstant>(enumerator.t).v};
2958 Symbol *symbol{FindSymbol(name)};
2960 // Contrary to named constants appearing in a PARAMETER statement,
2961 // enumerator names should not have their type, dimension or any other
2962 // attributes defined before they are declared in the enumerator statement.
2963 // This is not explicitly forbidden by the standard, but they are scalars
2964 // which type is left for the compiler to chose, so do not let users try to
2965 // tamper with that.
2966 SayAlreadyDeclared(name, *symbol);
2969 // Enumerators are treated as PARAMETER (section 7.6 paragraph (4))
2970 symbol = &MakeSymbol(name, Attrs{Attr::PARAMETER}, ObjectEntityDetails{});
2971 symbol->SetType(context().MakeNumericType(
2972 TypeCategory::Integer, evaluate::CInteger::kind));
2975 if (auto &init{std::get<std::optional<parser::ScalarIntConstantExpr>>(
2977 Walk(*init); // Resolve names in expression before evaluation.
2978 MaybeIntExpr expr{EvaluateIntExpr(*init)};
2979 if (auto value{evaluate::ToInt64(expr)}) {
2980 // Cast all init expressions to C_INT so that they can then be
2981 // safely incremented (see 7.6 Note 2).
2982 enumerationState_.value = static_cast<int>(*value);
2985 "Enumerator value could not be computed "
2986 "from the given expression"_err_en_US);
2987 // Prevent resolution of next enumerators value
2988 enumerationState_.value = std::nullopt;
2993 if (enumerationState_.value) {
2994 symbol->get<ObjectEntityDetails>().set_init(SomeExpr{
2995 evaluate::Expr<evaluate::CInteger>{*enumerationState_.value}});
2997 context().SetError(*symbol);
3001 if (enumerationState_.value) {
3002 (*enumerationState_.value)++;
3007 void DeclarationVisitor::Post(const parser::EnumDef &) {
3008 enumerationState_ = EnumeratorState{};
3011 bool DeclarationVisitor::Pre(const parser::AsynchronousStmt &x) {
3012 return HandleAttributeStmt(Attr::ASYNCHRONOUS, x.v);
3014 bool DeclarationVisitor::Pre(const parser::ContiguousStmt &x) {
3015 return HandleAttributeStmt(Attr::CONTIGUOUS, x.v);
3017 bool DeclarationVisitor::Pre(const parser::ExternalStmt &x) {
3018 HandleAttributeStmt(Attr::EXTERNAL, x.v);
3019 for (const auto &name : x.v) {
3020 auto *symbol{FindSymbol(name)};
3021 if (!ConvertToProcEntity(*symbol)) {
3023 name, *symbol, "EXTERNAL attribute not allowed on '%s'"_err_en_US);
3028 bool DeclarationVisitor::Pre(const parser::IntentStmt &x) {
3029 auto &intentSpec{std::get<parser::IntentSpec>(x.t)};
3030 auto &names{std::get<std::list<parser::Name>>(x.t)};
3031 return CheckNotInBlock("INTENT") && // C1107
3032 HandleAttributeStmt(IntentSpecToAttr(intentSpec), names);
3034 bool DeclarationVisitor::Pre(const parser::IntrinsicStmt &x) {
3035 HandleAttributeStmt(Attr::INTRINSIC, x.v);
3036 for (const auto &name : x.v) {
3037 auto *symbol{FindSymbol(name)};
3038 if (!ConvertToProcEntity(*symbol)) {
3040 name, *symbol, "INTRINSIC attribute not allowed on '%s'"_err_en_US);
3041 } else if (symbol->attrs().test(Attr::EXTERNAL)) { // C840
3043 "Symbol '%s' cannot have both EXTERNAL and INTRINSIC attributes"_err_en_US,
3049 bool DeclarationVisitor::Pre(const parser::OptionalStmt &x) {
3050 return CheckNotInBlock("OPTIONAL") && // C1107
3051 HandleAttributeStmt(Attr::OPTIONAL, x.v);
3053 bool DeclarationVisitor::Pre(const parser::ProtectedStmt &x) {
3054 return HandleAttributeStmt(Attr::PROTECTED, x.v);
3056 bool DeclarationVisitor::Pre(const parser::ValueStmt &x) {
3057 return CheckNotInBlock("VALUE") && // C1107
3058 HandleAttributeStmt(Attr::VALUE, x.v);
3060 bool DeclarationVisitor::Pre(const parser::VolatileStmt &x) {
3061 return HandleAttributeStmt(Attr::VOLATILE, x.v);
3063 // Handle a statement that sets an attribute on a list of names.
3064 bool DeclarationVisitor::HandleAttributeStmt(
3065 Attr attr, const std::list<parser::Name> &names) {
3066 for (const auto &name : names) {
3067 HandleAttributeStmt(attr, name);
3071 Symbol &DeclarationVisitor::HandleAttributeStmt(
3072 Attr attr, const parser::Name &name) {
3073 if (attr == Attr::INTRINSIC &&
3074 !context().intrinsics().IsIntrinsic(name.source.ToString())) {
3075 Say(name.source, "'%s' is not a known intrinsic procedure"_err_en_US);
3077 auto *symbol{FindInScope(currScope(), name)};
3078 if (attr == Attr::ASYNCHRONOUS || attr == Attr::VOLATILE) {
3079 // these can be set on a symbol that is host-assoc or use-assoc
3081 (currScope().kind() == Scope::Kind::Subprogram ||
3082 currScope().kind() == Scope::Kind::Block)) {
3083 if (auto *hostSymbol{FindSymbol(name)}) {
3084 name.symbol = nullptr;
3085 symbol = &MakeSymbol(name, HostAssocDetails{*hostSymbol});
3088 } else if (symbol && symbol->has<UseDetails>()) {
3089 Say(currStmtSource().value(),
3090 "Cannot change %s attribute on use-associated '%s'"_err_en_US,
3091 EnumToString(attr), name.source);
3095 symbol = &MakeSymbol(name, EntityDetails{});
3097 symbol->attrs().set(attr);
3098 symbol->attrs() = HandleSaveName(name.source, symbol->attrs());
3102 bool DeclarationVisitor::CheckNotInBlock(const char *stmt) {
3103 if (currScope().kind() == Scope::Kind::Block) {
3104 Say(MessageFormattedText{
3105 "%s statement is not allowed in a BLOCK construct"_err_en_US, stmt});
3112 void DeclarationVisitor::Post(const parser::ObjectDecl &x) {
3113 CHECK(objectDeclAttr_);
3114 const auto &name{std::get<parser::ObjectName>(x.t)};
3115 DeclareObjectEntity(name, Attrs{*objectDeclAttr_});
3118 // Declare an entity not yet known to be an object or proc.
3119 Symbol &DeclarationVisitor::DeclareUnknownEntity(
3120 const parser::Name &name, Attrs attrs) {
3121 if (!arraySpec().empty() || !coarraySpec().empty()) {
3122 return DeclareObjectEntity(name, attrs);
3124 Symbol &symbol{DeclareEntity<EntityDetails>(name, attrs)};
3125 if (auto *type{GetDeclTypeSpec()}) {
3126 SetType(name, *type);
3128 charInfo_.length.reset();
3129 SetBindNameOn(symbol);
3130 if (symbol.attrs().test(Attr::EXTERNAL)) {
3131 ConvertToProcEntity(symbol);
3137 Symbol &DeclarationVisitor::DeclareProcEntity(
3138 const parser::Name &name, Attrs attrs, const ProcInterface &interface) {
3139 Symbol &symbol{DeclareEntity<ProcEntityDetails>(name, attrs)};
3140 if (auto *details{symbol.detailsIf<ProcEntityDetails>()}) {
3141 if (interface.type()) {
3142 symbol.set(Symbol::Flag::Function);
3143 } else if (interface.symbol()) {
3144 if (interface.symbol()->test(Symbol::Flag::Function)) {
3145 symbol.set(Symbol::Flag::Function);
3146 } else if (interface.symbol()->test(Symbol::Flag::Subroutine)) {
3147 symbol.set(Symbol::Flag::Subroutine);
3150 details->set_interface(interface);
3151 SetBindNameOn(symbol);
3152 SetPassNameOn(symbol);
3157 Symbol &DeclarationVisitor::DeclareObjectEntity(
3158 const parser::Name &name, Attrs attrs) {
3159 Symbol &symbol{DeclareEntity<ObjectEntityDetails>(name, attrs)};
3160 if (auto *details{symbol.detailsIf<ObjectEntityDetails>()}) {
3161 if (auto *type{GetDeclTypeSpec()}) {
3162 SetType(name, *type);
3164 if (!arraySpec().empty()) {
3165 if (details->IsArray()) {
3167 "The dimensions of '%s' have already been declared"_err_en_US);
3168 context().SetError(symbol);
3170 details->set_shape(arraySpec());
3173 if (!coarraySpec().empty()) {
3174 if (details->IsCoarray()) {
3176 "The codimensions of '%s' have already been declared"_err_en_US);
3177 context().SetError(symbol);
3179 details->set_coshape(coarraySpec());
3182 SetBindNameOn(symbol);
3186 charInfo_.length.reset();
3190 void DeclarationVisitor::Post(const parser::IntegerTypeSpec &x) {
3191 SetDeclTypeSpec(MakeNumericType(TypeCategory::Integer, x.v));
3193 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Real &x) {
3194 SetDeclTypeSpec(MakeNumericType(TypeCategory::Real, x.kind));
3196 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Complex &x) {
3197 SetDeclTypeSpec(MakeNumericType(TypeCategory::Complex, x.kind));
3199 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Logical &x) {
3200 SetDeclTypeSpec(MakeLogicalType(x.kind));
3202 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Character &) {
3203 if (!charInfo_.length) {
3204 charInfo_.length = ParamValue{1, common::TypeParamAttr::Len};
3206 if (!charInfo_.kind) {
3208 KindExpr{context().GetDefaultKind(TypeCategory::Character)};
3210 SetDeclTypeSpec(currScope().MakeCharacterType(
3211 std::move(*charInfo_.length), std::move(*charInfo_.kind)));
3214 void DeclarationVisitor::Post(const parser::CharSelector::LengthAndKind &x) {
3215 charInfo_.kind = EvaluateSubscriptIntExpr(x.kind);
3217 charInfo_.length = GetParamValue(*x.length, common::TypeParamAttr::Len);
3220 void DeclarationVisitor::Post(const parser::CharLength &x) {
3221 if (const auto *length{std::get_if<std::uint64_t>(&x.u)}) {
3222 charInfo_.length = ParamValue{
3223 static_cast<ConstantSubscript>(*length), common::TypeParamAttr::Len};
3225 charInfo_.length = GetParamValue(
3226 std::get<parser::TypeParamValue>(x.u), common::TypeParamAttr::Len);
3229 void DeclarationVisitor::Post(const parser::LengthSelector &x) {
3230 if (const auto *param{std::get_if<parser::TypeParamValue>(&x.u)}) {
3231 charInfo_.length = GetParamValue(*param, common::TypeParamAttr::Len);
3235 bool DeclarationVisitor::Pre(const parser::KindParam &x) {
3236 if (const auto *kind{std::get_if<
3237 parser::Scalar<parser::Integer<parser::Constant<parser::Name>>>>(
3239 const parser::Name &name{kind->thing.thing.thing};
3240 if (!FindSymbol(name)) {
3241 Say(name, "Parameter '%s' not found"_err_en_US);
3247 bool DeclarationVisitor::Pre(const parser::DeclarationTypeSpec::Type &) {
3248 CHECK(GetDeclTypeSpecCategory() == DeclTypeSpec::Category::TypeDerived);
3252 bool DeclarationVisitor::Pre(const parser::DeclarationTypeSpec::Class &) {
3253 SetDeclTypeSpecCategory(DeclTypeSpec::Category::ClassDerived);
3257 bool DeclarationVisitor::Pre(const parser::DeclarationTypeSpec::Record &) {
3262 void DeclarationVisitor::Post(const parser::DerivedTypeSpec &x) {
3263 const auto &typeName{std::get<parser::Name>(x.t)};
3264 auto spec{ResolveDerivedType(typeName)};
3268 bool seenAnyName{false};
3269 for (const auto &typeParamSpec :
3270 std::get<std::list<parser::TypeParamSpec>>(x.t)) {
3271 const auto &optKeyword{
3272 std::get<std::optional<parser::Keyword>>(typeParamSpec.t)};
3273 std::optional<SourceName> name;
3276 name = optKeyword->v.source;
3277 } else if (seenAnyName) {
3278 Say(typeName.source, "Type parameter value must have a name"_err_en_US);
3281 const auto &value{std::get<parser::TypeParamValue>(typeParamSpec.t)};
3282 // The expressions in a derived type specifier whose values define
3283 // non-defaulted type parameters are evaluated (folded) in the enclosing
3284 // scope. The KIND/LEN distinction is resolved later in
3285 // DerivedTypeSpec::CookParameters().
3286 ParamValue param{GetParamValue(value, common::TypeParamAttr::Kind)};
3287 if (!param.isExplicit() || param.GetExplicit()) {
3288 spec->AddRawParamValue(optKeyword, std::move(param));
3292 // The DerivedTypeSpec *spec is used initially as a search key.
3293 // If it turns out to have the same name and actual parameter
3294 // value expressions as another DerivedTypeSpec in the current
3295 // scope does, then we'll use that extant spec; otherwise, when this
3296 // spec is distinct from all derived types previously instantiated
3297 // in the current scope, this spec will be moved into that collection.
3298 const auto &dtDetails{spec->typeSymbol().get<DerivedTypeDetails>()};
3299 auto category{GetDeclTypeSpecCategory()};
3300 if (dtDetails.isForwardReferenced()) {
3301 DeclTypeSpec &type{currScope().MakeDerivedType(category, std::move(*spec))};
3302 SetDeclTypeSpec(type);
3305 // Normalize parameters to produce a better search key.
3306 spec->CookParameters(GetFoldingContext());
3307 if (!spec->MightBeParameterized()) {
3308 spec->EvaluateParameters(GetFoldingContext());
3310 if (const DeclTypeSpec *
3311 extant{currScope().FindInstantiatedDerivedType(*spec, category)}) {
3312 // This derived type and parameter expressions (if any) are already present
3314 SetDeclTypeSpec(*extant);
3316 DeclTypeSpec &type{currScope().MakeDerivedType(category, std::move(*spec))};
3317 DerivedTypeSpec &derived{type.derivedTypeSpec()};
3318 if (derived.MightBeParameterized() &&
3319 currScope().IsParameterizedDerivedType()) {
3320 // Defer instantiation; use the derived type's definition's scope.
3321 derived.set_scope(DEREF(spec->typeSymbol().scope()));
3324 GetFoldingContext().messages().SetLocation(currStmtSource().value())};
3325 derived.Instantiate(currScope(), context());
3327 SetDeclTypeSpec(type);
3329 // Capture the DerivedTypeSpec in the parse tree for use in building
3330 // structure constructor expressions.
3331 x.derivedTypeSpec = &GetDeclTypeSpec()->derivedTypeSpec();
3334 // The descendents of DerivedTypeDef in the parse tree are visited directly
3335 // in this Pre() routine so that recursive use of the derived type can be
3336 // supported in the components.
3337 bool DeclarationVisitor::Pre(const parser::DerivedTypeDef &x) {
3338 auto &stmt{std::get<parser::Statement<parser::DerivedTypeStmt>>(x.t)};
3340 Walk(std::get<std::list<parser::Statement<parser::TypeParamDefStmt>>>(x.t));
3341 auto &scope{currScope()};
3342 CHECK(scope.symbol());
3343 CHECK(scope.symbol()->scope() == &scope);
3344 auto &details{scope.symbol()->get<DerivedTypeDetails>()};
3345 std::set<SourceName> paramNames;
3346 for (auto ¶mName : std::get<std::list<parser::Name>>(stmt.statement.t)) {
3347 details.add_paramName(paramName.source);
3348 auto *symbol{FindInScope(scope, paramName)};
3351 "No definition found for type parameter '%s'"_err_en_US); // C742
3352 } else if (!symbol->has<TypeParamDetails>()) {
3353 Say2(paramName, "'%s' is not defined as a type parameter"_err_en_US,
3354 *symbol, "Definition of '%s'"_en_US); // C741
3356 if (!paramNames.insert(paramName.source).second) {
3358 "Duplicate type parameter name: '%s'"_err_en_US); // C731
3361 for (const auto &[name, symbol] : currScope()) {
3362 if (symbol->has<TypeParamDetails>() && !paramNames.count(name)) {
3363 SayDerivedType(name,
3364 "'%s' is not a type parameter of this derived type"_err_en_US,
3365 currScope()); // C742
3368 Walk(std::get<std::list<parser::Statement<parser::PrivateOrSequence>>>(x.t));
3369 if (derivedTypeInfo_.sequence) {
3370 details.set_sequence(true);
3371 if (derivedTypeInfo_.extends) {
3373 "A sequence type may not have the EXTENDS attribute"_err_en_US); // C735
3375 if (!details.paramNames().empty()) {
3377 "A sequence type may not have type parameters"_err_en_US); // C740
3380 Walk(std::get<std::list<parser::Statement<parser::ComponentDefStmt>>>(x.t));
3381 Walk(std::get<std::optional<parser::TypeBoundProcedurePart>>(x.t));
3382 Walk(std::get<parser::Statement<parser::EndTypeStmt>>(x.t));
3383 derivedTypeInfo_ = {};
3387 bool DeclarationVisitor::Pre(const parser::DerivedTypeStmt &) {
3388 return BeginAttrs();
3390 void DeclarationVisitor::Post(const parser::DerivedTypeStmt &x) {
3391 auto &name{std::get<parser::Name>(x.t)};
3392 // Resolve the EXTENDS() clause before creating the derived
3393 // type's symbol to foil attempts to recursively extend a type.
3394 auto *extendsName{derivedTypeInfo_.extends};
3395 std::optional<DerivedTypeSpec> extendsType{
3396 ResolveExtendsType(name, extendsName)};
3397 auto &symbol{MakeSymbol(name, GetAttrs(), DerivedTypeDetails{})};
3398 symbol.ReplaceName(name.source);
3399 derivedTypeInfo_.type = &symbol;
3400 PushScope(Scope::Kind::DerivedType, &symbol);
3402 // Declare the "parent component"; private if the type is.
3403 // Any symbol stored in the EXTENDS() clause is temporarily
3404 // hidden so that a new symbol can be created for the parent
3405 // component without producing spurious errors about already
3407 const Symbol &extendsSymbol{extendsType->typeSymbol()};
3408 auto restorer{common::ScopedSet(extendsName->symbol, nullptr)};
3409 if (OkToAddComponent(*extendsName, &extendsSymbol)) {
3410 auto &comp{DeclareEntity<ObjectEntityDetails>(*extendsName, Attrs{})};
3412 Attr::PRIVATE, extendsSymbol.attrs().test(Attr::PRIVATE));
3413 comp.set(Symbol::Flag::ParentComp);
3414 DeclTypeSpec &type{currScope().MakeDerivedType(
3415 DeclTypeSpec::TypeDerived, std::move(*extendsType))};
3416 type.derivedTypeSpec().set_scope(*extendsSymbol.scope());
3418 DerivedTypeDetails &details{symbol.get<DerivedTypeDetails>()};
3419 details.add_component(comp);
3425 void DeclarationVisitor::Post(const parser::TypeParamDefStmt &x) {
3426 auto *type{GetDeclTypeSpec()};
3427 auto attr{std::get<common::TypeParamAttr>(x.t)};
3428 for (auto &decl : std::get<std::list<parser::TypeParamDecl>>(x.t)) {
3429 auto &name{std::get<parser::Name>(decl.t)};
3430 if (Symbol * symbol{MakeTypeSymbol(name, TypeParamDetails{attr})}) {
3431 SetType(name, *type);
3433 std::get<std::optional<parser::ScalarIntConstantExpr>>(decl.t)}) {
3434 if (auto maybeExpr{EvaluateConvertedExpr(
3435 *symbol, *init, init->thing.thing.thing.value().source)}) {
3436 auto *intExpr{std::get_if<SomeIntExpr>(&maybeExpr->u)};
3438 symbol->get<TypeParamDetails>().set_init(std::move(*intExpr));
3445 bool DeclarationVisitor::Pre(const parser::TypeAttrSpec::Extends &x) {
3446 derivedTypeInfo_.extends = &x.v;
3450 bool DeclarationVisitor::Pre(const parser::PrivateStmt &) {
3451 if (!currScope().parent().IsModule()) {
3452 Say("PRIVATE is only allowed in a derived type that is"
3453 " in a module"_err_en_US); // C766
3454 } else if (derivedTypeInfo_.sawContains) {
3455 derivedTypeInfo_.privateBindings = true;
3456 } else if (!derivedTypeInfo_.privateComps) {
3457 derivedTypeInfo_.privateComps = true;
3459 Say("PRIVATE may not appear more than once in"
3460 " derived type components"_en_US); // C738
3464 bool DeclarationVisitor::Pre(const parser::SequenceStmt &) {
3465 derivedTypeInfo_.sequence = true;
3468 void DeclarationVisitor::Post(const parser::ComponentDecl &x) {
3469 const auto &name{std::get<parser::Name>(x.t)};
3470 auto attrs{GetAttrs()};
3471 if (derivedTypeInfo_.privateComps &&
3472 !attrs.HasAny({Attr::PUBLIC, Attr::PRIVATE})) {
3473 attrs.set(Attr::PRIVATE);
3475 if (!attrs.HasAny({Attr::POINTER, Attr::ALLOCATABLE})) {
3476 if (const auto *declType{GetDeclTypeSpec()}) {
3477 if (const auto *derived{declType->AsDerived()}) {
3478 if (derivedTypeInfo_.type == &derived->typeSymbol()) { // C737
3479 Say("Recursive use of the derived type requires "
3480 "POINTER or ALLOCATABLE"_err_en_US);
3485 if (OkToAddComponent(name)) {
3486 auto &symbol{DeclareObjectEntity(name, attrs)};
3487 if (symbol.has<ObjectEntityDetails>()) {
3488 if (auto &init{std::get<std::optional<parser::Initialization>>(x.t)}) {
3489 Initialization(name, *init, true);
3492 currScope().symbol()->get<DerivedTypeDetails>().add_component(symbol);
3497 bool DeclarationVisitor::Pre(const parser::ProcedureDeclarationStmt &) {
3498 CHECK(!interfaceName_);
3501 void DeclarationVisitor::Post(const parser::ProcedureDeclarationStmt &) {
3502 interfaceName_ = nullptr;
3505 bool DeclarationVisitor::Pre(const parser::DataComponentDefStmt &x) {
3506 // Overrides parse tree traversal so as to handle attributes first,
3507 // so POINTER & ALLOCATABLE enable forward references to derived types.
3508 Walk(std::get<std::list<parser::ComponentAttrSpec>>(x.t));
3509 set_allowForwardReferenceToDerivedType(
3510 GetAttrs().test(Attr::POINTER) || GetAttrs().test(Attr::ALLOCATABLE));
3511 Walk(std::get<parser::DeclarationTypeSpec>(x.t));
3512 set_allowForwardReferenceToDerivedType(false);
3513 Walk(std::get<std::list<parser::ComponentDecl>>(x.t));
3516 bool DeclarationVisitor::Pre(const parser::ProcComponentDefStmt &) {
3517 CHECK(!interfaceName_);
3520 void DeclarationVisitor::Post(const parser::ProcComponentDefStmt &) {
3521 interfaceName_ = nullptr;
3523 bool DeclarationVisitor::Pre(const parser::ProcPointerInit &x) {
3524 if (auto *name{std::get_if<parser::Name>(&x.u)}) {
3525 return !NameIsKnownOrIntrinsic(*name);
3529 void DeclarationVisitor::Post(const parser::ProcInterface &x) {
3530 if (auto *name{std::get_if<parser::Name>(&x.u)}) {
3531 interfaceName_ = name;
3532 NoteInterfaceName(*name);
3536 void DeclarationVisitor::Post(const parser::ProcDecl &x) {
3537 const auto &name{std::get<parser::Name>(x.t)};
3538 ProcInterface interface;
3539 if (interfaceName_) {
3540 interface.set_symbol(*interfaceName_->symbol);
3541 } else if (auto *type{GetDeclTypeSpec()}) {
3542 interface.set_type(*type);
3544 auto attrs{HandleSaveName(name.source, GetAttrs())};
3545 DerivedTypeDetails *dtDetails{nullptr};
3546 if (Symbol * symbol{currScope().symbol()}) {
3547 dtDetails = symbol->detailsIf<DerivedTypeDetails>();
3550 attrs.set(Attr::EXTERNAL);
3552 Symbol &symbol{DeclareProcEntity(name, attrs, interface)};
3554 dtDetails->add_component(symbol);
3558 bool DeclarationVisitor::Pre(const parser::TypeBoundProcedurePart &) {
3559 derivedTypeInfo_.sawContains = true;
3563 // Resolve binding names from type-bound generics, saved in genericBindings_.
3564 void DeclarationVisitor::Post(const parser::TypeBoundProcedurePart &) {
3565 // track specifics seen for the current generic to detect duplicates:
3566 const Symbol *currGeneric{nullptr};
3567 std::set<SourceName> specifics;
3568 for (const auto [generic, bindingName] : genericBindings_) {
3569 if (generic != currGeneric) {
3570 currGeneric = generic;
3573 auto [it, inserted]{specifics.insert(bindingName->source)};
3575 Say(*bindingName, // C773
3576 "Binding name '%s' was already specified for generic '%s'"_err_en_US,
3577 bindingName->source, generic->name())
3578 .Attach(*it, "Previous specification of '%s'"_en_US, *it);
3581 auto *symbol{FindInTypeOrParents(*bindingName)};
3583 Say(*bindingName, // C772
3584 "Binding name '%s' not found in this derived type"_err_en_US);
3585 } else if (!symbol->has<ProcBindingDetails>()) {
3586 SayWithDecl(*bindingName, *symbol, // C772
3587 "'%s' is not the name of a specific binding of this type"_err_en_US);
3589 generic->get<GenericDetails>().AddSpecificProc(
3590 *symbol, bindingName->source);
3593 genericBindings_.clear();
3596 void DeclarationVisitor::Post(const parser::ContainsStmt &) {
3597 if (derivedTypeInfo_.sequence) {
3598 Say("A sequence type may not have a CONTAINS statement"_err_en_US); // C740
3602 void DeclarationVisitor::Post(
3603 const parser::TypeBoundProcedureStmt::WithoutInterface &x) {
3604 if (GetAttrs().test(Attr::DEFERRED)) { // C783
3605 Say("DEFERRED is only allowed when an interface-name is provided"_err_en_US);
3607 for (auto &declaration : x.declarations) {
3608 auto &bindingName{std::get<parser::Name>(declaration.t)};
3609 auto &optName{std::get<std::optional<parser::Name>>(declaration.t)};
3610 const parser::Name &procedureName{optName ? *optName : bindingName};
3611 Symbol *procedure{FindSymbol(procedureName)};
3613 procedure = NoteInterfaceName(procedureName);
3615 if (auto *s{MakeTypeSymbol(bindingName, ProcBindingDetails{*procedure})}) {
3617 if (GetAttrs().test(Attr::DEFERRED)) {
3618 context().SetError(*s);
3624 void DeclarationVisitor::CheckBindings(
3625 const parser::TypeBoundProcedureStmt::WithoutInterface &tbps) {
3626 CHECK(currScope().IsDerivedType());
3627 for (auto &declaration : tbps.declarations) {
3628 auto &bindingName{std::get<parser::Name>(declaration.t)};
3629 if (Symbol * binding{FindInScope(currScope(), bindingName)}) {
3630 if (auto *details{binding->detailsIf<ProcBindingDetails>()}) {
3631 const Symbol *procedure{FindSubprogram(details->symbol())};
3632 if (!CanBeTypeBoundProc(procedure)) {
3633 if (details->symbol().name() != binding->name()) {
3634 Say(binding->name(),
3635 "The binding of '%s' ('%s') must be either an accessible "
3636 "module procedure or an external procedure with "
3637 "an explicit interface"_err_en_US,
3638 binding->name(), details->symbol().name());
3640 Say(binding->name(),
3641 "'%s' must be either an accessible module procedure "
3642 "or an external procedure with an explicit interface"_err_en_US,
3645 context().SetError(*binding);
3652 void DeclarationVisitor::Post(
3653 const parser::TypeBoundProcedureStmt::WithInterface &x) {
3654 if (!GetAttrs().test(Attr::DEFERRED)) { // C783
3655 Say("DEFERRED is required when an interface-name is provided"_err_en_US);
3657 if (Symbol * interface{NoteInterfaceName(x.interfaceName)}) {
3658 for (auto &bindingName : x.bindingNames) {
3660 MakeTypeSymbol(bindingName, ProcBindingDetails{*interface})}) {
3662 if (!GetAttrs().test(Attr::DEFERRED)) {
3663 context().SetError(*s);
3670 void DeclarationVisitor::Post(const parser::FinalProcedureStmt &x) {
3671 for (auto &name : x.v) {
3672 MakeTypeSymbol(name, FinalProcDetails{});
3676 bool DeclarationVisitor::Pre(const parser::TypeBoundGenericStmt &x) {
3677 const auto &accessSpec{std::get<std::optional<parser::AccessSpec>>(x.t)};
3678 const auto &genericSpec{std::get<Indirection<parser::GenericSpec>>(x.t)};
3679 const auto &bindingNames{std::get<std::list<parser::Name>>(x.t)};
3680 auto info{GenericSpecInfo{genericSpec.value()}};
3681 SourceName symbolName{info.symbolName()};
3682 bool isPrivate{accessSpec ? accessSpec->v == parser::AccessSpec::Kind::Private
3683 : derivedTypeInfo_.privateBindings};
3684 auto *genericSymbol{info.FindInScope(context(), currScope())};
3685 if (genericSymbol) {
3686 if (!genericSymbol->has<GenericDetails>()) {
3687 genericSymbol = nullptr; // MakeTypeSymbol will report the error below
3690 // look in parent types:
3691 Symbol *inheritedSymbol{nullptr};
3692 for (const auto &name : info.GetAllNames(context())) {
3693 inheritedSymbol = currScope().FindComponent(SourceName{name});
3694 if (inheritedSymbol) {
3698 if (inheritedSymbol && inheritedSymbol->has<GenericDetails>()) {
3699 CheckAccessibility(symbolName, isPrivate, *inheritedSymbol); // C771
3702 if (genericSymbol) {
3703 CheckAccessibility(symbolName, isPrivate, *genericSymbol); // C771
3705 genericSymbol = MakeTypeSymbol(symbolName, GenericDetails{});
3706 if (!genericSymbol) {
3710 genericSymbol->attrs().set(Attr::PRIVATE);
3713 for (const parser::Name &bindingName : bindingNames) {
3714 genericBindings_.emplace(genericSymbol, &bindingName);
3716 info.Resolve(genericSymbol);
3720 bool DeclarationVisitor::Pre(const parser::AllocateStmt &) {
3721 BeginDeclTypeSpec();
3724 void DeclarationVisitor::Post(const parser::AllocateStmt &) {
3728 bool DeclarationVisitor::Pre(const parser::StructureConstructor &x) {
3729 auto &parsedType{std::get<parser::DerivedTypeSpec>(x.t)};
3730 const DeclTypeSpec *type{ProcessTypeSpec(parsedType)};
3734 const DerivedTypeSpec *spec{type->AsDerived()};
3735 const Scope *typeScope{spec ? spec->scope() : nullptr};
3740 // N.B C7102 is implicitly enforced by having inaccessible types not
3741 // being found in resolution.
3742 // More constraints are enforced in expression.cpp so that they
3743 // can apply to structure constructors that have been converted
3744 // from misparsed function references.
3745 for (const auto &component :
3746 std::get<std::list<parser::ComponentSpec>>(x.t)) {
3747 // Visit the component spec expression, but not the keyword, since
3748 // we need to resolve its symbol in the scope of the derived type.
3749 Walk(std::get<parser::ComponentDataSource>(component.t));
3750 if (const auto &kw{std::get<std::optional<parser::Keyword>>(component.t)}) {
3751 if (Symbol * symbol{FindInTypeOrParents(*typeScope, kw->v)}) {
3752 if (!kw->v.symbol) {
3753 kw->v.symbol = symbol;
3755 CheckAccessibleComponent(kw->v.source, *symbol);
3762 bool DeclarationVisitor::Pre(const parser::BasedPointerStmt &x) {
3763 for (const parser::BasedPointer &bp : x.v) {
3764 const parser::ObjectName &pointerName{std::get<0>(bp.t)};
3765 const parser::ObjectName &pointeeName{std::get<1>(bp.t)};
3766 auto *pointer{FindSymbol(pointerName)};
3768 pointer = &MakeSymbol(pointerName, ObjectEntityDetails{});
3769 } else if (!ConvertToObjectEntity(*pointer) || IsNamedConstant(*pointer)) {
3770 SayWithDecl(pointerName, *pointer, "'%s' is not a variable"_err_en_US);
3771 } else if (pointer->Rank() > 0) {
3772 SayWithDecl(pointerName, *pointer,
3773 "Cray pointer '%s' must be a scalar"_err_en_US);
3774 } else if (pointer->test(Symbol::Flag::CrayPointee)) {
3776 "'%s' cannot be a Cray pointer as it is already a Cray pointee"_err_en_US);
3778 pointer->set(Symbol::Flag::CrayPointer);
3779 const DeclTypeSpec &pointerType{MakeNumericType(TypeCategory::Integer,
3780 context().defaultKinds().subscriptIntegerKind())};
3781 const auto *type{pointer->GetType()};
3783 pointer->SetType(pointerType);
3784 } else if (*type != pointerType) {
3785 Say(pointerName.source, "Cray pointer '%s' must have type %s"_err_en_US,
3786 pointerName.source, pointerType.AsFortran());
3788 if (ResolveName(pointeeName)) {
3789 Symbol &pointee{*pointeeName.symbol};
3790 if (pointee.has<UseDetails>()) {
3792 "'%s' cannot be a Cray pointee as it is use-associated"_err_en_US);
3794 } else if (!ConvertToObjectEntity(pointee) || IsNamedConstant(pointee)) {
3795 Say(pointeeName, "'%s' is not a variable"_err_en_US);
3797 } else if (pointee.test(Symbol::Flag::CrayPointer)) {
3799 "'%s' cannot be a Cray pointee as it is already a Cray pointer"_err_en_US);
3800 } else if (pointee.test(Symbol::Flag::CrayPointee)) {
3802 "'%s' was already declared as a Cray pointee"_err_en_US);
3804 pointee.set(Symbol::Flag::CrayPointee);
3806 if (const auto *pointeeType{pointee.GetType()}) {
3807 if (const auto *derived{pointeeType->AsDerived()}) {
3808 if (!derived->typeSymbol().get<DerivedTypeDetails>().sequence()) {
3810 "Type of Cray pointee '%s' is a non-sequence derived type"_err_en_US);
3814 // process the pointee array-spec, if present
3816 Walk(std::get<std::optional<parser::ArraySpec>>(bp.t));
3817 const auto &spec{arraySpec()};
3818 if (!spec.empty()) {
3819 auto &details{pointee.get<ObjectEntityDetails>()};
3820 if (details.shape().empty()) {
3821 details.set_shape(spec);
3823 SayWithDecl(pointeeName, pointee,
3824 "Array spec was already declared for '%s'"_err_en_US);
3828 currScope().add_crayPointer(pointeeName.source, *pointer);
3834 bool DeclarationVisitor::Pre(const parser::NamelistStmt::Group &x) {
3835 if (!CheckNotInBlock("NAMELIST")) { // C1107
3839 NamelistDetails details;
3840 for (const auto &name : std::get<std::list<parser::Name>>(x.t)) {
3841 auto *symbol{FindSymbol(name)};
3843 symbol = &MakeSymbol(name, ObjectEntityDetails{});
3844 ApplyImplicitRules(*symbol);
3845 } else if (!ConvertToObjectEntity(*symbol)) {
3846 SayWithDecl(name, *symbol, "'%s' is not a variable"_err_en_US);
3848 details.add_object(*symbol);
3851 const auto &groupName{std::get<parser::Name>(x.t)};
3852 auto *groupSymbol{FindInScope(currScope(), groupName)};
3854 groupSymbol = &MakeSymbol(groupName, std::move(details));
3855 } else if (groupSymbol->has<NamelistDetails>()) {
3856 groupSymbol->get<NamelistDetails>().add_objects(details.objects());
3858 SayAlreadyDeclared(groupName, *groupSymbol);
3863 bool DeclarationVisitor::Pre(const parser::IoControlSpec &x) {
3864 if (const auto *name{std::get_if<parser::Name>(&x.u)}) {
3865 auto *symbol{FindSymbol(*name)};
3867 Say(*name, "Namelist group '%s' not found"_err_en_US);
3868 } else if (!symbol->GetUltimate().has<NamelistDetails>()) {
3870 *name, *symbol, "'%s' is not the name of a namelist group"_err_en_US);
3876 bool DeclarationVisitor::Pre(const parser::CommonStmt::Block &x) {
3877 CheckNotInBlock("COMMON"); // C1107
3878 const auto &optName{std::get<std::optional<parser::Name>>(x.t)};
3879 parser::Name blankCommon;
3880 blankCommon.source =
3881 SourceName{currStmtSource().value().begin(), std::size_t{0}};
3882 CHECK(!commonBlockInfo_.curr);
3883 commonBlockInfo_.curr =
3884 &MakeCommonBlockSymbol(optName ? *optName : blankCommon);
3888 void DeclarationVisitor::Post(const parser::CommonStmt::Block &) {
3889 commonBlockInfo_.curr = nullptr;
3892 bool DeclarationVisitor::Pre(const parser::CommonBlockObject &) {
3897 void DeclarationVisitor::Post(const parser::CommonBlockObject &x) {
3898 CHECK(commonBlockInfo_.curr);
3899 const auto &name{std::get<parser::Name>(x.t)};
3900 auto &symbol{DeclareObjectEntity(name, Attrs{})};
3903 auto *details{symbol.detailsIf<ObjectEntityDetails>()};
3905 return; // error was reported
3907 commonBlockInfo_.curr->get<CommonBlockDetails>().add_object(symbol);
3908 auto pair{commonBlockInfo_.names.insert(name.source)};
3910 const SourceName &prev{*pair.first};
3911 Say2(name.source, "'%s' is already in a COMMON block"_err_en_US, prev,
3912 "Previous occurrence of '%s' in a COMMON block"_en_US);
3915 details->set_commonBlock(*commonBlockInfo_.curr);
3918 bool DeclarationVisitor::Pre(const parser::EquivalenceStmt &x) {
3919 // save equivalence sets to be processed after specification part
3920 CheckNotInBlock("EQUIVALENCE"); // C1107
3921 for (const std::list<parser::EquivalenceObject> &set : x.v) {
3922 equivalenceSets_.push_back(&set);
3924 return false; // don't implicitly declare names yet
3927 void DeclarationVisitor::CheckEquivalenceSets() {
3928 EquivalenceSets equivSets{context()};
3929 for (const auto *set : equivalenceSets_) {
3930 const auto &source{set->front().v.value().source};
3931 if (set->size() <= 1) { // R871
3932 Say(source, "Equivalence set must have more than one object"_err_en_US);
3934 for (const parser::EquivalenceObject &object : *set) {
3935 const auto &designator{object.v.value()};
3936 // The designator was not resolved when it was encountered so do it now.
3937 // AnalyzeExpr causes array sections to be changed to substrings as needed
3939 if (AnalyzeExpr(context(), designator)) {
3940 equivSets.AddToSet(designator);
3943 equivSets.FinishSet(source);
3945 for (auto &set : equivSets.sets()) {
3947 currScope().add_equivalenceSet(std::move(set));
3950 equivalenceSets_.clear();
3953 bool DeclarationVisitor::Pre(const parser::SaveStmt &x) {
3955 saveInfo_.saveAll = currStmtSource();
3957 for (const parser::SavedEntity &y : x.v) {
3958 auto kind{std::get<parser::SavedEntity::Kind>(y.t)};
3959 const auto &name{std::get<parser::Name>(y.t)};
3960 if (kind == parser::SavedEntity::Kind::Common) {
3961 MakeCommonBlockSymbol(name);
3962 AddSaveName(saveInfo_.commons, name.source);
3964 HandleAttributeStmt(Attr::SAVE, name);
3971 void DeclarationVisitor::CheckSaveStmts() {
3972 for (const SourceName &name : saveInfo_.entities) {
3973 auto *symbol{FindInScope(currScope(), name)};
3975 // error was reported
3976 } else if (saveInfo_.saveAll) {
3977 // C889 - note that pgi, ifort, xlf do not enforce this constraint
3979 "Explicit SAVE of '%s' is redundant due to global SAVE statement"_err_en_US,
3980 *saveInfo_.saveAll, "Global SAVE statement"_en_US);
3981 } else if (auto msg{CheckSaveAttr(*symbol)}) {
3982 Say(name, std::move(*msg));
3984 SetSaveAttr(*symbol);
3987 for (const SourceName &name : saveInfo_.commons) {
3988 if (auto *symbol{currScope().FindCommonBlock(name)}) {
3989 auto &objects{symbol->get<CommonBlockDetails>().objects()};
3990 if (objects.empty()) {
3991 if (currScope().kind() != Scope::Kind::Block) {
3993 "'%s' appears as a COMMON block in a SAVE statement but not in"
3994 " a COMMON statement"_err_en_US);
3997 "SAVE statement in BLOCK construct may not contain a"
3998 " common block name '%s'"_err_en_US);
4001 for (const Symbol &object :
4002 symbol->get<CommonBlockDetails>().objects()) {
4003 SetSaveAttr(*const_cast<Symbol *>(&object));
4008 if (saveInfo_.saveAll) {
4009 // Apply SAVE attribute to applicable symbols
4010 for (auto pair : currScope()) {
4011 auto &symbol{*pair.second};
4012 if (!CheckSaveAttr(symbol)) {
4013 SetSaveAttr(symbol);
4020 // If SAVE attribute can't be set on symbol, return error message.
4021 std::optional<MessageFixedText> DeclarationVisitor::CheckSaveAttr(
4022 const Symbol &symbol) {
4023 if (symbol.IsDummy()) {
4024 return "SAVE attribute may not be applied to dummy argument '%s'"_err_en_US;
4025 } else if (symbol.IsFuncResult()) {
4026 return "SAVE attribute may not be applied to function result '%s'"_err_en_US;
4027 } else if (symbol.has<ProcEntityDetails>() &&
4028 !symbol.attrs().test(Attr::POINTER)) {
4029 return "Procedure '%s' with SAVE attribute must also have POINTER attribute"_err_en_US;
4031 return std::nullopt;
4035 // Instead of setting SAVE attribute, record the name in saveInfo_.entities.
4036 Attrs DeclarationVisitor::HandleSaveName(const SourceName &name, Attrs attrs) {
4037 if (attrs.test(Attr::SAVE)) {
4038 attrs.set(Attr::SAVE, false);
4039 AddSaveName(saveInfo_.entities, name);
4044 // Record a name in a set of those to be saved.
4045 void DeclarationVisitor::AddSaveName(
4046 std::set<SourceName> &set, const SourceName &name) {
4047 auto pair{set.insert(name)};
4049 Say2(name, "SAVE attribute was already specified on '%s'"_err_en_US,
4050 *pair.first, "Previous specification of SAVE attribute"_en_US);
4054 // Set the SAVE attribute on symbol unless it is implicitly saved anyway.
4055 void DeclarationVisitor::SetSaveAttr(Symbol &symbol) {
4056 if (!IsSaved(symbol)) {
4057 symbol.attrs().set(Attr::SAVE);
4061 // Check types of common block objects, now that they are known.
4062 void DeclarationVisitor::CheckCommonBlocks() {
4063 // check for empty common blocks
4064 for (const auto pair : currScope().commonBlocks()) {
4065 const auto &symbol{*pair.second};
4066 if (symbol.get<CommonBlockDetails>().objects().empty() &&
4067 symbol.attrs().test(Attr::BIND_C)) {
4069 "'%s' appears as a COMMON block in a BIND statement but not in"
4070 " a COMMON statement"_err_en_US);
4073 // check objects in common blocks
4074 for (const auto &name : commonBlockInfo_.names) {
4075 const auto *symbol{currScope().FindSymbol(name)};
4079 const auto &attrs{symbol->attrs()};
4080 if (attrs.test(Attr::ALLOCATABLE)) {
4082 "ALLOCATABLE object '%s' may not appear in a COMMON block"_err_en_US);
4083 } else if (attrs.test(Attr::BIND_C)) {
4085 "Variable '%s' with BIND attribute may not appear in a COMMON block"_err_en_US);
4086 } else if (symbol->IsDummy()) {
4088 "Dummy argument '%s' may not appear in a COMMON block"_err_en_US);
4089 } else if (symbol->IsFuncResult()) {
4091 "Function result '%s' may not appear in a COMMON block"_err_en_US);
4092 } else if (const DeclTypeSpec * type{symbol->GetType()}) {
4093 if (type->category() == DeclTypeSpec::ClassStar) {
4095 "Unlimited polymorphic pointer '%s' may not appear in a COMMON block"_err_en_US);
4096 } else if (const auto *derived{type->AsDerived()}) {
4097 auto &typeSymbol{derived->typeSymbol()};
4098 if (!typeSymbol.attrs().test(Attr::BIND_C) &&
4099 !typeSymbol.get<DerivedTypeDetails>().sequence()) {
4101 "Derived type '%s' in COMMON block must have the BIND or"
4102 " SEQUENCE attribute"_err_en_US);
4104 CheckCommonBlockDerivedType(name, typeSymbol);
4108 commonBlockInfo_ = {};
4111 Symbol &DeclarationVisitor::MakeCommonBlockSymbol(const parser::Name &name) {
4112 return Resolve(name, currScope().MakeCommonBlock(name.source));
4115 bool DeclarationVisitor::NameIsKnownOrIntrinsic(const parser::Name &name) {
4116 return FindSymbol(name) || HandleUnrestrictedSpecificIntrinsicFunction(name);
4119 // Check if this derived type can be in a COMMON block.
4120 void DeclarationVisitor::CheckCommonBlockDerivedType(
4121 const SourceName &name, const Symbol &typeSymbol) {
4122 if (const auto *scope{typeSymbol.scope()}) {
4123 for (const auto &pair : *scope) {
4124 const Symbol &component{*pair.second};
4125 if (component.attrs().test(Attr::ALLOCATABLE)) {
4127 "Derived type variable '%s' may not appear in a COMMON block"
4128 " due to ALLOCATABLE component"_err_en_US,
4129 component.name(), "Component with ALLOCATABLE attribute"_en_US);
4132 if (const auto *details{component.detailsIf<ObjectEntityDetails>()}) {
4133 if (details->init()) {
4135 "Derived type variable '%s' may not appear in a COMMON block"
4136 " due to component with default initialization"_err_en_US,
4137 component.name(), "Component with default initialization"_en_US);
4140 if (const auto *type{details->type()}) {
4141 if (const auto *derived{type->AsDerived()}) {
4142 CheckCommonBlockDerivedType(name, derived->typeSymbol());
4150 bool DeclarationVisitor::HandleUnrestrictedSpecificIntrinsicFunction(
4151 const parser::Name &name) {
4152 if (auto interface{context().intrinsics().IsSpecificIntrinsicFunction(
4153 name.source.ToString())}) {
4154 // Unrestricted specific intrinsic function names (e.g., "cos")
4155 // are acceptable as procedure interfaces.
4157 MakeSymbol(InclusiveScope(), name.source, Attrs{Attr::INTRINSIC})};
4158 if (interface->IsElemental()) {
4159 symbol.attrs().set(Attr::ELEMENTAL);
4161 symbol.set_details(ProcEntityDetails{});
4162 Resolve(name, symbol);
4169 // Checks for all locality-specs: LOCAL, LOCAL_INIT, and SHARED
4170 bool DeclarationVisitor::PassesSharedLocalityChecks(
4171 const parser::Name &name, Symbol &symbol) {
4172 if (!IsVariableName(symbol)) {
4173 SayLocalMustBeVariable(name, symbol); // C1124
4176 if (symbol.owner() == currScope()) { // C1125 and C1126
4177 SayAlreadyDeclared(name, symbol);
4183 // Checks for locality-specs LOCAL and LOCAL_INIT
4184 bool DeclarationVisitor::PassesLocalityChecks(
4185 const parser::Name &name, Symbol &symbol) {
4186 if (IsAllocatable(symbol)) { // C1128
4187 SayWithDecl(name, symbol,
4188 "ALLOCATABLE variable '%s' not allowed in a locality-spec"_err_en_US);
4191 if (IsOptional(symbol)) { // C1128
4192 SayWithDecl(name, symbol,
4193 "OPTIONAL argument '%s' not allowed in a locality-spec"_err_en_US);
4196 if (IsIntentIn(symbol)) { // C1128
4197 SayWithDecl(name, symbol,
4198 "INTENT IN argument '%s' not allowed in a locality-spec"_err_en_US);
4201 if (IsFinalizable(symbol)) { // C1128
4202 SayWithDecl(name, symbol,
4203 "Finalizable variable '%s' not allowed in a locality-spec"_err_en_US);
4206 if (IsCoarray(symbol)) { // C1128
4208 name, symbol, "Coarray '%s' not allowed in a locality-spec"_err_en_US);
4211 if (const DeclTypeSpec * type{symbol.GetType()}) {
4212 if (type->IsPolymorphic() && symbol.IsDummy() &&
4213 !IsPointer(symbol)) { // C1128
4214 SayWithDecl(name, symbol,
4215 "Nonpointer polymorphic argument '%s' not allowed in a "
4216 "locality-spec"_err_en_US);
4220 if (IsAssumedSizeArray(symbol)) { // C1128
4221 SayWithDecl(name, symbol,
4222 "Assumed size array '%s' not allowed in a locality-spec"_err_en_US);
4225 if (std::optional<MessageFixedText> msg{
4226 WhyNotModifiable(symbol, currScope())}) {
4227 SayWithReason(name, symbol,
4228 "'%s' may not appear in a locality-spec because it is not "
4229 "definable"_err_en_US,
4233 return PassesSharedLocalityChecks(name, symbol);
4236 Symbol &DeclarationVisitor::FindOrDeclareEnclosingEntity(
4237 const parser::Name &name) {
4238 Symbol *prev{FindSymbol(name)};
4240 // Declare the name as an object in the enclosing scope so that
4241 // the name can't be repurposed there later as something else.
4242 prev = &MakeSymbol(InclusiveScope(), name.source, Attrs{});
4243 ConvertToObjectEntity(*prev);
4244 ApplyImplicitRules(*prev);
4249 Symbol *DeclarationVisitor::DeclareLocalEntity(const parser::Name &name) {
4250 Symbol &prev{FindOrDeclareEnclosingEntity(name)};
4251 if (!PassesLocalityChecks(name, prev)) {
4254 name.symbol = nullptr;
4255 Symbol &symbol{DeclareEntity<ObjectEntityDetails>(name, {})};
4256 if (auto *type{prev.GetType()}) {
4257 symbol.SetType(*type);
4258 symbol.set(Symbol::Flag::Implicit, prev.test(Symbol::Flag::Implicit));
4263 Symbol *DeclarationVisitor::DeclareStatementEntity(const parser::Name &name,
4264 const std::optional<parser::IntegerTypeSpec> &type) {
4265 const DeclTypeSpec *declTypeSpec{nullptr};
4266 if (auto *prev{FindSymbol(name)}) {
4267 if (prev->owner() == currScope()) {
4268 SayAlreadyDeclared(name, *prev);
4271 name.symbol = nullptr;
4272 declTypeSpec = prev->GetType();
4274 Symbol &symbol{DeclareEntity<ObjectEntityDetails>(name, {})};
4275 if (!symbol.has<ObjectEntityDetails>()) {
4276 return nullptr; // error was reported in DeclareEntity
4279 declTypeSpec = ProcessTypeSpec(*type);
4282 // Subtlety: Don't let a "*length" specifier (if any is pending) affect the
4283 // declaration of this implied DO loop control variable.
4285 common::ScopedSet(charInfo_.length, std::optional<ParamValue>{})};
4286 SetType(name, *declTypeSpec);
4288 ApplyImplicitRules(symbol);
4290 return Resolve(name, &symbol);
4293 // Set the type of an entity or report an error.
4294 void DeclarationVisitor::SetType(
4295 const parser::Name &name, const DeclTypeSpec &type) {
4297 auto &symbol{*name.symbol};
4298 if (charInfo_.length) { // Declaration has "*length" (R723)
4299 auto length{std::move(*charInfo_.length)};
4300 charInfo_.length.reset();
4301 if (type.category() == DeclTypeSpec::Character) {
4302 auto kind{type.characterTypeSpec().kind()};
4303 // Recurse with correct type.
4305 currScope().MakeCharacterType(std::move(length), std::move(kind)));
4309 "A length specifier cannot be used to declare the non-character entity '%s'"_err_en_US);
4312 auto *prevType{symbol.GetType()};
4314 symbol.SetType(type);
4315 } else if (symbol.has<UseDetails>()) {
4316 // error recovery case, redeclaration of use-associated name
4317 } else if (!symbol.test(Symbol::Flag::Implicit)) {
4319 name, symbol, "The type of '%s' has already been declared"_err_en_US);
4320 } else if (type != *prevType) {
4321 SayWithDecl(name, symbol,
4322 "The type of '%s' has already been implicitly declared"_err_en_US);
4324 symbol.set(Symbol::Flag::Implicit, false);
4328 std::optional<DerivedTypeSpec> DeclarationVisitor::ResolveDerivedType(
4329 const parser::Name &name) {
4330 Symbol *symbol{FindSymbol(name)};
4331 if (!symbol || symbol->has<UnknownDetails>()) {
4332 if (allowForwardReferenceToDerivedType()) {
4334 symbol = &MakeSymbol(InclusiveScope(), name.source, Attrs{});
4335 Resolve(name, *symbol);
4337 DerivedTypeDetails details;
4338 details.set_isForwardReferenced();
4339 symbol->set_details(std::move(details));
4341 Say(name, "Derived type '%s' not found"_err_en_US);
4342 return std::nullopt;
4345 if (CheckUseError(name)) {
4346 return std::nullopt;
4348 symbol = &symbol->GetUltimate();
4349 if (auto *details{symbol->detailsIf<GenericDetails>()}) {
4350 if (details->derivedType()) {
4351 symbol = details->derivedType();
4354 if (symbol->has<DerivedTypeDetails>()) {
4355 return DerivedTypeSpec{name.source, *symbol};
4357 Say(name, "'%s' is not a derived type"_err_en_US);
4358 return std::nullopt;
4362 std::optional<DerivedTypeSpec> DeclarationVisitor::ResolveExtendsType(
4363 const parser::Name &typeName, const parser::Name *extendsName) {
4365 return std::nullopt;
4366 } else if (typeName.source == extendsName->source) {
4367 Say(extendsName->source,
4368 "Derived type '%s' cannot extend itself"_err_en_US);
4369 return std::nullopt;
4371 return ResolveDerivedType(*extendsName);
4375 Symbol *DeclarationVisitor::NoteInterfaceName(const parser::Name &name) {
4376 // The symbol is checked later by CheckExplicitInterface() and
4377 // CheckBindings(). It can be a forward reference.
4378 if (!NameIsKnownOrIntrinsic(name)) {
4379 Symbol &symbol{MakeSymbol(InclusiveScope(), name.source, Attrs{})};
4380 Resolve(name, symbol);
4385 void DeclarationVisitor::CheckExplicitInterface(const parser::Name &name) {
4386 if (const Symbol * symbol{name.symbol}) {
4387 if (!symbol->HasExplicitInterface()) {
4389 "'%s' must be an abstract interface or a procedure with "
4390 "an explicit interface"_err_en_US,
4396 // Create a symbol for a type parameter, component, or procedure binding in
4397 // the current derived type scope. Return false on error.
4398 Symbol *DeclarationVisitor::MakeTypeSymbol(
4399 const parser::Name &name, Details &&details) {
4400 return Resolve(name, MakeTypeSymbol(name.source, std::move(details)));
4402 Symbol *DeclarationVisitor::MakeTypeSymbol(
4403 const SourceName &name, Details &&details) {
4404 Scope &derivedType{currScope()};
4405 CHECK(derivedType.IsDerivedType());
4406 if (auto *symbol{FindInScope(derivedType, name)}) {
4408 "Type parameter, component, or procedure binding '%s'"
4409 " already defined in this type"_err_en_US,
4410 *symbol, "Previous definition of '%s'"_en_US);
4413 auto attrs{GetAttrs()};
4414 // Apply binding-private-stmt if present and this is a procedure binding
4415 if (derivedTypeInfo_.privateBindings &&
4416 !attrs.HasAny({Attr::PUBLIC, Attr::PRIVATE}) &&
4417 std::holds_alternative<ProcBindingDetails>(details)) {
4418 attrs.set(Attr::PRIVATE);
4420 Symbol &result{MakeSymbol(name, attrs, std::move(details))};
4421 if (result.has<TypeParamDetails>()) {
4422 derivedType.symbol()->get<DerivedTypeDetails>().add_paramDecl(result);
4428 // Return true if it is ok to declare this component in the current scope.
4429 // Otherwise, emit an error and return false.
4430 bool DeclarationVisitor::OkToAddComponent(
4431 const parser::Name &name, const Symbol *extends) {
4432 for (const Scope *scope{&currScope()}; scope;) {
4433 CHECK(scope->IsDerivedType());
4434 if (auto *prev{FindInScope(*scope, name)}) {
4437 msg = "Type cannot be extended as it has a component named"
4439 } else if (prev->test(Symbol::Flag::ParentComp)) {
4440 msg = "'%s' is a parent type of this type and so cannot be"
4441 " a component"_err_en_US;
4442 } else if (scope != &currScope()) {
4443 msg = "Component '%s' is already declared in a parent of this"
4444 " derived type"_err_en_US;
4446 msg = "Component '%s' is already declared in this"
4447 " derived type"_err_en_US;
4449 Say2(name, std::move(msg), *prev, "Previous declaration of '%s'"_en_US);
4452 if (scope == &currScope() && extends) {
4453 // The parent component has not yet been added to the scope.
4454 scope = extends->scope();
4456 scope = scope->GetDerivedTypeParent();
4462 ParamValue DeclarationVisitor::GetParamValue(
4463 const parser::TypeParamValue &x, common::TypeParamAttr attr) {
4466 [=](const parser::ScalarIntExpr &x) {
4467 return ParamValue{EvaluateIntExpr(x), attr};
4469 [=](const parser::Star &) { return ParamValue::Assumed(attr); },
4470 [=](const parser::TypeParamValue::Deferred &) {
4471 return ParamValue::Deferred(attr);
4477 // ConstructVisitor implementation
4479 void ConstructVisitor::ResolveIndexName(
4480 const parser::ConcurrentControl &control) {
4481 const parser::Name &name{std::get<parser::Name>(control.t)};
4482 auto *prev{FindSymbol(name)};
4484 if (prev->owner().kind() == Scope::Kind::Forall ||
4485 prev->owner() == currScope()) {
4486 SayAlreadyDeclared(name, *prev);
4489 name.symbol = nullptr;
4491 auto &symbol{DeclareObjectEntity(name, {})};
4493 if (symbol.GetType()) {
4494 // type came from explicit type-spec
4496 ApplyImplicitRules(symbol);
4497 } else if (!prev->has<ObjectEntityDetails>() && !prev->has<EntityDetails>()) {
4498 Say2(name, "Index name '%s' conflicts with existing identifier"_err_en_US,
4499 *prev, "Previous declaration of '%s'"_en_US);
4502 if (const auto *type{prev->GetType()}) {
4503 symbol.SetType(*type);
4505 if (prev->IsObjectArray()) {
4506 SayWithDecl(name, *prev, "Index variable '%s' is not scalar"_err_en_US);
4510 EvaluateExpr(parser::Scalar{parser::Integer{common::Clone(name)}});
4513 // We need to make sure that all of the index-names get declared before the
4514 // expressions in the loop control are evaluated so that references to the
4515 // index-names in the expressions are correctly detected.
4516 bool ConstructVisitor::Pre(const parser::ConcurrentHeader &header) {
4517 BeginDeclTypeSpec();
4518 Walk(std::get<std::optional<parser::IntegerTypeSpec>>(header.t));
4519 const auto &controls{
4520 std::get<std::list<parser::ConcurrentControl>>(header.t)};
4521 for (const auto &control : controls) {
4522 ResolveIndexName(control);
4525 Walk(std::get<std::optional<parser::ScalarLogicalExpr>>(header.t));
4530 bool ConstructVisitor::Pre(const parser::LocalitySpec::Local &x) {
4531 for (auto &name : x.v) {
4532 if (auto *symbol{DeclareLocalEntity(name)}) {
4533 symbol->set(Symbol::Flag::LocalityLocal);
4539 bool ConstructVisitor::Pre(const parser::LocalitySpec::LocalInit &x) {
4540 for (auto &name : x.v) {
4541 if (auto *symbol{DeclareLocalEntity(name)}) {
4542 symbol->set(Symbol::Flag::LocalityLocalInit);
4548 bool ConstructVisitor::Pre(const parser::LocalitySpec::Shared &x) {
4549 for (const auto &name : x.v) {
4550 if (!FindSymbol(name)) {
4551 Say(name, "Variable '%s' with SHARED locality implicitly declared"_en_US);
4553 Symbol &prev{FindOrDeclareEnclosingEntity(name)};
4554 if (PassesSharedLocalityChecks(name, prev)) {
4555 auto &symbol{MakeSymbol(name, HostAssocDetails{prev})};
4556 symbol.set(Symbol::Flag::LocalityShared);
4557 name.symbol = &symbol; // override resolution to parent
4563 bool ConstructVisitor::Pre(const parser::AcSpec &x) {
4564 ProcessTypeSpec(x.type);
4565 PushScope(Scope::Kind::ImpliedDos, nullptr);
4571 bool ConstructVisitor::Pre(const parser::AcImpliedDo &x) {
4572 auto &values{std::get<std::list<parser::AcValue>>(x.t)};
4573 auto &control{std::get<parser::AcImpliedDoControl>(x.t)};
4574 auto &type{std::get<std::optional<parser::IntegerTypeSpec>>(control.t)};
4575 auto &bounds{std::get<parser::AcImpliedDoControl::Bounds>(control.t)};
4576 DeclareStatementEntity(bounds.name.thing.thing, type);
4582 bool ConstructVisitor::Pre(const parser::DataImpliedDo &x) {
4583 auto &objects{std::get<std::list<parser::DataIDoObject>>(x.t)};
4584 auto &type{std::get<std::optional<parser::IntegerTypeSpec>>(x.t)};
4585 auto &bounds{std::get<parser::DataImpliedDo::Bounds>(x.t)};
4586 DeclareStatementEntity(bounds.name.thing.thing, type);
4592 bool ConstructVisitor::Pre(const parser::DataStmtObject &x) {
4595 [&](const Indirection<parser::Variable> &y) {
4597 if (const auto *designator{
4598 std::get_if<Indirection<parser::Designator>>(
4600 if (const parser::Name *
4601 name{ResolveDesignator(designator->value())}) {
4603 name->symbol->set(Symbol::Flag::InDataStmt);
4606 // TODO check C874 - C881
4608 // TODO report C875 error: variable is not a designator here?
4611 [&](const parser::DataImpliedDo &y) {
4612 PushScope(Scope::Kind::ImpliedDos, nullptr);
4621 bool ConstructVisitor::Pre(const parser::DoConstruct &x) {
4622 if (x.IsDoConcurrent()) {
4623 PushScope(Scope::Kind::Block, nullptr);
4627 void ConstructVisitor::Post(const parser::DoConstruct &x) {
4628 if (x.IsDoConcurrent()) {
4633 bool ConstructVisitor::Pre(const parser::ForallConstruct &) {
4634 PushScope(Scope::Kind::Forall, nullptr);
4637 void ConstructVisitor::Post(const parser::ForallConstruct &) { PopScope(); }
4638 bool ConstructVisitor::Pre(const parser::ForallStmt &) {
4639 PushScope(Scope::Kind::Forall, nullptr);
4642 void ConstructVisitor::Post(const parser::ForallStmt &) { PopScope(); }
4644 bool ConstructVisitor::Pre(const parser::BlockStmt &x) {
4646 PushScope(Scope::Kind::Block, nullptr);
4649 bool ConstructVisitor::Pre(const parser::EndBlockStmt &x) {
4655 void ConstructVisitor::Post(const parser::Selector &x) {
4656 GetCurrentAssociation().selector = ResolveSelector(x);
4659 bool ConstructVisitor::Pre(const parser::AssociateStmt &x) {
4661 PushScope(Scope::Kind::Block, nullptr);
4665 void ConstructVisitor::Post(const parser::EndAssociateStmt &x) {
4671 void ConstructVisitor::Post(const parser::Association &x) {
4672 const auto &name{std::get<parser::Name>(x.t)};
4673 GetCurrentAssociation().name = &name;
4674 if (auto *symbol{MakeAssocEntity()}) {
4675 SetTypeFromAssociation(*symbol);
4676 SetAttrsFromAssociation(*symbol);
4678 GetCurrentAssociation() = {}; // clean for further parser::Association.
4681 bool ConstructVisitor::Pre(const parser::ChangeTeamStmt &x) {
4683 PushScope(Scope::Kind::Block, nullptr);
4688 void ConstructVisitor::Post(const parser::CoarrayAssociation &x) {
4689 const auto &decl{std::get<parser::CodimensionDecl>(x.t)};
4690 const auto &name{std::get<parser::Name>(decl.t)};
4691 if (auto *symbol{FindInScope(currScope(), name)}) {
4692 const auto &selector{std::get<parser::Selector>(x.t)};
4693 if (auto sel{ResolveSelector(selector)}) {
4694 const Symbol *whole{UnwrapWholeSymbolDataRef(sel.expr)};
4695 if (!whole || whole->Corank() == 0) {
4696 Say(sel.source, // C1116
4697 "Selector in coarray association must name a coarray"_err_en_US);
4698 } else if (auto dynType{sel.expr->GetType()}) {
4699 if (!symbol->GetType()) {
4700 symbol->SetType(ToDeclTypeSpec(std::move(*dynType)));
4707 void ConstructVisitor::Post(const parser::EndChangeTeamStmt &x) {
4713 bool ConstructVisitor::Pre(const parser::SelectTypeConstruct &) {
4718 void ConstructVisitor::Post(const parser::SelectTypeConstruct &) {
4722 void ConstructVisitor::Post(const parser::SelectTypeStmt &x) {
4723 auto &association{GetCurrentAssociation()};
4724 if (const std::optional<parser::Name> &name{std::get<1>(x.t)}) {
4725 // This isn't a name in the current scope, it is in each TypeGuardStmt
4726 MakePlaceholder(*name, MiscDetails::Kind::SelectTypeAssociateName);
4727 association.name = &*name;
4730 whole{UnwrapWholeSymbolDataRef(association.selector.expr)}) {
4731 ConvertToObjectEntity(const_cast<Symbol &>(*whole));
4732 if (!IsVariableName(*whole)) {
4733 Say(association.selector.source, // C901
4734 "Selector is not a variable"_err_en_US);
4738 Say(association.selector.source, // C1157
4739 "Selector is not a named variable: 'associate-name =>' is required"_err_en_US);
4745 bool ConstructVisitor::Pre(const parser::SelectTypeConstruct::TypeCase &) {
4746 PushScope(Scope::Kind::Block, nullptr);
4749 void ConstructVisitor::Post(const parser::SelectTypeConstruct::TypeCase &) {
4753 void ConstructVisitor::Post(const parser::TypeGuardStmt::Guard &x) {
4754 if (auto *symbol{MakeAssocEntity()}) {
4755 if (std::holds_alternative<parser::Default>(x.u)) {
4756 SetTypeFromAssociation(*symbol);
4757 } else if (const auto *type{GetDeclTypeSpec()}) {
4758 symbol->SetType(*type);
4760 SetAttrsFromAssociation(*symbol);
4764 bool ConstructVisitor::Pre(const parser::SelectRankConstruct &) {
4769 void ConstructVisitor::Post(const parser::SelectRankConstruct &) {
4773 bool ConstructVisitor::CheckDef(const std::optional<parser::Name> &x) {
4775 MakeSymbol(*x, MiscDetails{MiscDetails::Kind::ConstructName});
4780 void ConstructVisitor::CheckRef(const std::optional<parser::Name> &x) {
4782 // Just add an occurrence of this name; checking is done in ValidateLabels
4787 // Make a symbol representing an associating entity from current association.
4788 Symbol *ConstructVisitor::MakeAssocEntity() {
4789 Symbol *symbol{nullptr};
4790 auto &association{GetCurrentAssociation()};
4791 if (association.name) {
4792 symbol = &MakeSymbol(*association.name, UnknownDetails{});
4793 if (symbol->has<AssocEntityDetails>() && symbol->owner() == currScope()) {
4794 Say(*association.name, // C1104
4795 "The associate name '%s' is already used in this associate statement"_err_en_US);
4798 } else if (const Symbol *
4799 whole{UnwrapWholeSymbolDataRef(association.selector.expr)}) {
4800 symbol = &MakeSymbol(whole->name());
4804 if (auto &expr{association.selector.expr}) {
4805 symbol->set_details(AssocEntityDetails{common::Clone(*expr)});
4807 symbol->set_details(AssocEntityDetails{});
4812 // Set the type of symbol based on the current association selector.
4813 void ConstructVisitor::SetTypeFromAssociation(Symbol &symbol) {
4814 auto &details{symbol.get<AssocEntityDetails>()};
4815 const MaybeExpr *pexpr{&details.expr()};
4817 pexpr = &GetCurrentAssociation().selector.expr;
4820 const SomeExpr &expr{**pexpr};
4821 if (std::optional<evaluate::DynamicType> type{expr.GetType()}) {
4822 if (const auto *charExpr{
4823 evaluate::UnwrapExpr<evaluate::Expr<evaluate::SomeCharacter>>(
4825 symbol.SetType(ToDeclTypeSpec(std::move(*type),
4827 std::visit([](const auto &kindChar) { return kindChar.LEN(); },
4830 symbol.SetType(ToDeclTypeSpec(std::move(*type)));
4833 // BOZ literals, procedure designators, &c. are not acceptable
4834 Say(symbol.name(), "Associate name '%s' must have a type"_err_en_US);
4839 // If current selector is a variable, set some of its attributes on symbol.
4840 void ConstructVisitor::SetAttrsFromAssociation(Symbol &symbol) {
4841 Attrs attrs{evaluate::GetAttrs(GetCurrentAssociation().selector.expr)};
4842 symbol.attrs() |= attrs &
4843 Attrs{Attr::TARGET, Attr::ASYNCHRONOUS, Attr::VOLATILE, Attr::CONTIGUOUS};
4844 if (attrs.test(Attr::POINTER)) {
4845 symbol.attrs().set(Attr::TARGET);
4849 ConstructVisitor::Selector ConstructVisitor::ResolveSelector(
4850 const parser::Selector &x) {
4853 [&](const parser::Expr &expr) {
4854 return Selector{expr.source, EvaluateExpr(expr)};
4856 [&](const parser::Variable &var) {
4857 return Selector{var.GetSource(), EvaluateExpr(var)};
4863 ConstructVisitor::Association &ConstructVisitor::GetCurrentAssociation() {
4864 CHECK(!associationStack_.empty());
4865 return associationStack_.back();
4868 void ConstructVisitor::PushAssociation() {
4869 associationStack_.emplace_back(Association{});
4872 void ConstructVisitor::PopAssociation() {
4873 CHECK(!associationStack_.empty());
4874 associationStack_.pop_back();
4877 const DeclTypeSpec &ConstructVisitor::ToDeclTypeSpec(
4878 evaluate::DynamicType &&type) {
4879 switch (type.category()) {
4880 SWITCH_COVERS_ALL_CASES
4881 case common::TypeCategory::Integer:
4882 case common::TypeCategory::Real:
4883 case common::TypeCategory::Complex:
4884 return context().MakeNumericType(type.category(), type.kind());
4885 case common::TypeCategory::Logical:
4886 return context().MakeLogicalType(type.kind());
4887 case common::TypeCategory::Derived:
4888 if (type.IsAssumedType()) {
4889 return currScope().MakeTypeStarType();
4890 } else if (type.IsUnlimitedPolymorphic()) {
4891 return currScope().MakeClassStarType();
4893 return currScope().MakeDerivedType(
4894 type.IsPolymorphic() ? DeclTypeSpec::ClassDerived
4895 : DeclTypeSpec::TypeDerived,
4896 common::Clone(type.GetDerivedTypeSpec())
4900 case common::TypeCategory::Character: CRASH_NO_CASE;
4904 const DeclTypeSpec &ConstructVisitor::ToDeclTypeSpec(
4905 evaluate::DynamicType &&type, MaybeSubscriptIntExpr &&length) {
4906 CHECK(type.category() == common::TypeCategory::Character);
4908 return currScope().MakeCharacterType(
4909 ParamValue{SomeIntExpr{*std::move(length)}, common::TypeParamAttr::Len},
4910 KindExpr{type.kind()});
4912 return currScope().MakeCharacterType(
4913 ParamValue::Deferred(common::TypeParamAttr::Len),
4914 KindExpr{type.kind()});
4918 // ResolveNamesVisitor implementation
4920 // Ensures that bare undeclared intrinsic procedure names passed as actual
4921 // arguments get recognized as being intrinsics.
4922 bool ResolveNamesVisitor::Pre(const parser::ActualArg &arg) {
4923 if (const auto *expr{std::get_if<Indirection<parser::Expr>>(&arg.u)}) {
4924 if (const auto *designator{
4925 std::get_if<Indirection<parser::Designator>>(&expr->value().u)}) {
4926 if (const auto *dataRef{
4927 std::get_if<parser::DataRef>(&designator->value().u)}) {
4928 if (const auto *name{std::get_if<parser::Name>(&dataRef->u)}) {
4929 NameIsKnownOrIntrinsic(*name);
4937 bool ResolveNamesVisitor::Pre(const parser::FunctionReference &x) {
4938 HandleCall(Symbol::Flag::Function, x.v);
4941 bool ResolveNamesVisitor::Pre(const parser::CallStmt &x) {
4942 HandleCall(Symbol::Flag::Subroutine, x.v);
4946 bool ResolveNamesVisitor::Pre(const parser::ImportStmt &x) {
4947 auto &scope{currScope()};
4948 // Check C896 and C899: where IMPORT statements are allowed
4949 switch (scope.kind()) {
4950 case Scope::Kind::Module:
4951 if (scope.IsModule()) {
4952 Say("IMPORT is not allowed in a module scoping unit"_err_en_US);
4954 } else if (x.kind == common::ImportKind::None) {
4955 Say("IMPORT,NONE is not allowed in a submodule scoping unit"_err_en_US);
4959 case Scope::Kind::MainProgram:
4960 Say("IMPORT is not allowed in a main program scoping unit"_err_en_US);
4962 case Scope::Kind::Subprogram:
4963 if (scope.parent().IsGlobal()) {
4964 Say("IMPORT is not allowed in an external subprogram scoping unit"_err_en_US);
4968 case Scope::Kind::BlockData: // C1415 (in part)
4969 Say("IMPORT is not allowed in a BLOCK DATA subprogram"_err_en_US);
4973 if (auto error{scope.SetImportKind(x.kind)}) {
4974 Say(std::move(*error));
4976 for (auto &name : x.names) {
4977 if (FindSymbol(scope.parent(), name)) {
4978 scope.add_importName(name.source);
4980 Say(name, "'%s' not found in host scope"_err_en_US);
4983 prevImportStmt_ = currStmtSource();
4987 const parser::Name *DeclarationVisitor::ResolveStructureComponent(
4988 const parser::StructureComponent &x) {
4989 return FindComponent(ResolveDataRef(x.base), x.component);
4992 const parser::Name *DeclarationVisitor::ResolveDesignator(
4993 const parser::Designator &x) {
4996 [&](const parser::DataRef &x) { return ResolveDataRef(x); },
4997 [&](const parser::Substring &x) {
4998 return ResolveDataRef(std::get<parser::DataRef>(x.t));
5004 const parser::Name *DeclarationVisitor::ResolveDataRef(
5005 const parser::DataRef &x) {
5008 [=](const parser::Name &y) { return ResolveName(y); },
5009 [=](const Indirection<parser::StructureComponent> &y) {
5010 return ResolveStructureComponent(y.value());
5012 [&](const Indirection<parser::ArrayElement> &y) {
5013 Walk(y.value().subscripts);
5014 return ResolveDataRef(y.value().base);
5016 [&](const Indirection<parser::CoindexedNamedObject> &y) {
5017 Walk(y.value().imageSelector);
5018 return ResolveDataRef(y.value().base);
5024 const parser::Name *DeclarationVisitor::ResolveVariable(
5025 const parser::Variable &x) {
5028 [&](const Indirection<parser::Designator> &y) {
5029 return ResolveDesignator(y.value());
5031 [&](const Indirection<parser::FunctionReference> &y) {
5033 std::get<parser::ProcedureDesignator>(y.value().v.t)};
5036 [&](const parser::Name &z) { return &z; },
5037 [&](const parser::ProcComponentRef &z) {
5038 return ResolveStructureComponent(z.v.thing);
5047 // If implicit types are allowed, ensure name is in the symbol table.
5048 // Otherwise, report an error if it hasn't been declared.
5049 const parser::Name *DeclarationVisitor::ResolveName(const parser::Name &name) {
5050 if (Symbol * symbol{FindSymbol(name)}) {
5051 if (CheckUseError(name)) {
5052 return nullptr; // reported an error
5054 if (symbol->IsDummy() ||
5055 (!symbol->GetType() && FindCommonBlockContaining(*symbol))) {
5056 ConvertToObjectEntity(*symbol);
5057 ApplyImplicitRules(*symbol);
5061 if (isImplicitNoneType()) {
5062 Say(name, "No explicit type declared for '%s'"_err_en_US);
5065 // Create the symbol then ensure it is accessible
5066 MakeSymbol(InclusiveScope(), name.source, Attrs{});
5067 auto *symbol{FindSymbol(name)};
5070 "'%s' from host scoping unit is not accessible due to IMPORT"_err_en_US);
5073 ConvertToObjectEntity(*symbol);
5074 ApplyImplicitRules(*symbol);
5078 // base is a part-ref of a derived type; find the named component in its type.
5079 // Also handles intrinsic type parameter inquiries (%kind, %len) and
5080 // COMPLEX component references (%re, %im).
5081 const parser::Name *DeclarationVisitor::FindComponent(
5082 const parser::Name *base, const parser::Name &component) {
5083 if (!base || !base->symbol) {
5086 auto &symbol{base->symbol->GetUltimate()};
5087 if (!symbol.has<AssocEntityDetails>() && !ConvertToObjectEntity(symbol)) {
5088 SayWithDecl(*base, symbol,
5089 "'%s' is an invalid base for a component reference"_err_en_US);
5092 auto *type{symbol.GetType()};
5094 return nullptr; // should have already reported error
5096 if (const IntrinsicTypeSpec * intrinsic{type->AsIntrinsic()}) {
5097 auto name{component.ToString()};
5098 auto category{intrinsic->category()};
5099 MiscDetails::Kind miscKind{MiscDetails::Kind::None};
5100 if (name == "kind") {
5101 miscKind = MiscDetails::Kind::KindParamInquiry;
5102 } else if (category == TypeCategory::Character) {
5103 if (name == "len") {
5104 miscKind = MiscDetails::Kind::LenParamInquiry;
5106 } else if (category == TypeCategory::Complex) {
5108 miscKind = MiscDetails::Kind::ComplexPartRe;
5109 } else if (name == "im") {
5110 miscKind = MiscDetails::Kind::ComplexPartIm;
5113 if (miscKind != MiscDetails::Kind::None) {
5114 MakePlaceholder(component, miscKind);
5117 } else if (const DerivedTypeSpec * derived{type->AsDerived()}) {
5118 if (const Scope * scope{derived->scope()}) {
5119 if (Resolve(component, scope->FindComponent(component.source))) {
5120 if (CheckAccessibleComponent(component.source, *component.symbol)) {
5124 SayDerivedType(component.source,
5125 "Component '%s' not found in derived type '%s'"_err_en_US, *scope);
5130 if (symbol.test(Symbol::Flag::Implicit)) {
5132 "'%s' is not an object of derived type; it is implicitly typed"_err_en_US);
5135 *base, symbol, "'%s' is not an object of derived type"_err_en_US);
5141 void DeclarationVisitor::CheckInitialDataTarget(
5142 const Symbol &pointer, const SomeExpr &expr, SourceName source) {
5143 auto &messages{GetFoldingContext().messages()};
5144 auto restorer{messages.SetLocation(source)};
5145 if (!evaluate::IsInitialDataTarget(expr, messages)) {
5147 "Pointer '%s' cannot be initialized with a reference to a designator with non-constant subscripts"_err_en_US,
5151 if (pointer.Rank() != expr.Rank()) {
5153 "Pointer '%s' of rank %d cannot be initialized with a target of different rank (%d)"_err_en_US,
5154 pointer.name(), pointer.Rank(), expr.Rank());
5157 // TODO: check type compatibility
5158 // TODO: check non-deferred type parameter values
5159 // TODO: check contiguity if pointer is CONTIGUOUS
5162 void DeclarationVisitor::CheckInitialProcTarget(
5163 const Symbol &pointer, const parser::Name &target, SourceName source) {
5164 // C1519 - must be nonelemental external or module procedure,
5165 // or an unrestricted specific intrinsic function.
5166 if (const Symbol * targetSym{target.symbol}) {
5167 const Symbol &ultimate{targetSym->GetUltimate()};
5168 if (ultimate.attrs().test(Attr::INTRINSIC)) {
5169 } else if (!ultimate.attrs().test(Attr::EXTERNAL) &&
5170 ultimate.owner().kind() != Scope::Kind::Module) {
5172 "Procedure pointer '%s' initializer '%s' is neither "
5173 "an external nor a module procedure"_err_en_US,
5174 pointer.name(), ultimate.name());
5175 } else if (ultimate.attrs().test(Attr::ELEMENTAL)) {
5177 "Procedure pointer '%s' cannot be initialized with the "
5178 "elemental procedure '%s"_err_en_US,
5179 pointer.name(), ultimate.name());
5181 // TODO: Check the "shalls" in the 15.4.3.6 paragraphs 7-10.
5186 void DeclarationVisitor::Initialization(const parser::Name &name,
5187 const parser::Initialization &init, bool inComponentDecl) {
5191 if (std::holds_alternative<parser::InitialDataTarget>(init.u)) {
5192 // Defer analysis to the end of the specification parts so that forward
5193 // references work better.
5196 // Traversal of the initializer was deferred to here so that the
5197 // symbol being declared can be available for use in the expression, e.g.:
5198 // real, parameter :: x = tiny(x)
5200 Symbol &ultimate{name.symbol->GetUltimate()};
5201 if (auto *details{ultimate.detailsIf<ObjectEntityDetails>()}) {
5202 // TODO: check C762 - all bounds and type parameters of component
5203 // are colons or constant expressions if component is initialized
5204 bool isPointer{false};
5207 [&](const parser::ConstantExpr &expr) {
5208 if (inComponentDecl) {
5209 // Can't convert to type of component, which might not yet
5210 // be known; that's done later during instantiation.
5211 if (MaybeExpr value{EvaluateExpr(expr)}) {
5212 details->set_init(std::move(*value));
5215 if (MaybeExpr folded{EvaluateConvertedExpr(
5216 ultimate, expr, expr.thing.value().source)}) {
5217 details->set_init(std::move(*folded));
5221 [&](const parser::NullInit &) {
5223 details->set_init(SomeExpr{evaluate::NullPointer{}});
5225 [&](const parser::InitialDataTarget &initExpr) {
5227 if (MaybeExpr expr{EvaluateExpr(initExpr)}) {
5228 CheckInitialDataTarget(
5229 ultimate, *expr, initExpr.value().source);
5230 details->set_init(std::move(*expr));
5233 [&](const std::list<Indirection<parser::DataStmtValue>> &) {
5234 if (inComponentDecl) {
5236 "Component '%s' initialized with DATA statement values"_err_en_US);
5238 // TODO - DATA statements and DATA-like initialization extension
5244 if (!IsPointer(ultimate)) {
5246 "Non-pointer component '%s' initialized with pointer target"_err_en_US);
5249 if (IsPointer(ultimate)) {
5251 "Object pointer component '%s' initialized with non-pointer expression"_err_en_US);
5252 } else if (IsAllocatable(ultimate)) {
5253 Say(name, "Allocatable component '%s' cannot be initialized"_err_en_US);
5259 void DeclarationVisitor::PointerInitialization(
5260 const parser::Name &name, const parser::InitialDataTarget &target) {
5262 Symbol &ultimate{name.symbol->GetUltimate()};
5263 if (IsPointer(ultimate)) {
5264 if (auto *details{ultimate.detailsIf<ObjectEntityDetails>()}) {
5265 CHECK(!details->init());
5267 if (MaybeExpr expr{EvaluateExpr(target)}) {
5268 CheckInitialDataTarget(ultimate, *expr, target.value().source);
5269 details->set_init(std::move(*expr));
5273 Say(name, "'%s' is not a pointer but is initialized like one"_err_en_US);
5277 void DeclarationVisitor::PointerInitialization(
5278 const parser::Name &name, const parser::ProcPointerInit &target) {
5280 Symbol &ultimate{name.symbol->GetUltimate()};
5281 if (IsProcedurePointer(ultimate)) {
5282 auto &details{ultimate.get<ProcEntityDetails>()};
5283 CHECK(!details.init());
5285 if (const auto *targetName{std::get_if<parser::Name>(&target.u)}) {
5286 CheckInitialProcTarget(ultimate, *targetName, name.source);
5287 if (targetName->symbol) {
5288 details.set_init(*targetName->symbol);
5291 details.set_init(nullptr); // explicit NULL()
5295 "'%s' is not a procedure pointer but is initialized "
5296 "like one"_err_en_US);
5301 void ResolveNamesVisitor::HandleCall(
5302 Symbol::Flag procFlag, const parser::Call &call) {
5305 [&](const parser::Name &x) { HandleProcedureName(procFlag, x); },
5306 [&](const parser::ProcComponentRef &x) { Walk(x); },
5308 std::get<parser::ProcedureDesignator>(call.t).u);
5309 Walk(std::get<std::list<parser::ActualArgSpec>>(call.t));
5312 void ResolveNamesVisitor::HandleProcedureName(
5313 Symbol::Flag flag, const parser::Name &name) {
5314 CHECK(flag == Symbol::Flag::Function || flag == Symbol::Flag::Subroutine);
5315 auto *symbol{FindSymbol(name)};
5317 if (context().intrinsics().IsIntrinsic(name.source.ToString())) {
5319 &MakeSymbol(InclusiveScope(), name.source, Attrs{Attr::INTRINSIC});
5321 symbol = &MakeSymbol(context().globalScope(), name.source, Attrs{});
5323 Resolve(name, *symbol);
5324 if (symbol->has<ModuleDetails>()) {
5325 SayWithDecl(name, *symbol,
5326 "Use of '%s' as a procedure conflicts with its declaration"_err_en_US);
5329 if (!symbol->attrs().test(Attr::INTRINSIC)) {
5330 if (isImplicitNoneExternal() && !symbol->attrs().test(Attr::EXTERNAL)) {
5332 "'%s' is an external procedure without the EXTERNAL"
5333 " attribute in a scope with IMPLICIT NONE(EXTERNAL)"_err_en_US);
5336 MakeExternal(*symbol);
5338 ConvertToProcEntity(*symbol);
5339 SetProcFlag(name, *symbol, flag);
5340 } else if (symbol->has<UnknownDetails>()) {
5341 DIE("unexpected UnknownDetails");
5342 } else if (CheckUseError(name)) {
5343 // error was reported
5345 symbol = &Resolve(name, symbol)->GetUltimate();
5346 ConvertToProcEntity(*symbol);
5347 if (!SetProcFlag(name, *symbol, flag)) {
5348 return; // reported error
5350 if (IsProcedure(*symbol) || symbol->has<DerivedTypeDetails>() ||
5351 symbol->has<ObjectEntityDetails>() ||
5352 symbol->has<AssocEntityDetails>()) {
5353 // Symbols with DerivedTypeDetails, ObjectEntityDetails and
5354 // AssocEntityDetails are accepted here as procedure-designators because
5355 // this means the related FunctionReference are mis-parsed structure
5356 // constructors or array references that will be fixed later when
5357 // analyzing expressions.
5358 } else if (symbol->test(Symbol::Flag::Implicit)) {
5360 "Use of '%s' as a procedure conflicts with its implicit definition"_err_en_US);
5362 SayWithDecl(name, *symbol,
5363 "Use of '%s' as a procedure conflicts with its declaration"_err_en_US);
5368 // Variant of HandleProcedureName() for use while skimming the executable
5369 // part of a subprogram to catch calls to dummy procedures that are part
5370 // of the subprogram's interface, and to mark as procedures any symbols
5371 // that might otherwise have been miscategorized as objects.
5372 void ResolveNamesVisitor::NoteExecutablePartCall(
5373 Symbol::Flag flag, const parser::Call &call) {
5374 auto &designator{std::get<parser::ProcedureDesignator>(call.t)};
5375 if (const auto *name{std::get_if<parser::Name>(&designator.u)}) {
5376 // Subtlety: The symbol pointers in the parse tree are not set, because
5377 // they might end up resolving elsewhere (e.g., construct entities in
5379 if (Symbol * symbol{currScope().FindSymbol(name->source)}) {
5380 Symbol::Flag other{flag == Symbol::Flag::Subroutine
5381 ? Symbol::Flag::Function
5382 : Symbol::Flag::Subroutine};
5383 if (!symbol->test(other)) {
5384 ConvertToProcEntity(*symbol);
5385 if (symbol->has<ProcEntityDetails>()) {
5387 if (symbol->IsDummy()) {
5388 symbol->attrs().set(Attr::EXTERNAL);
5390 ApplyImplicitRules(*symbol);
5397 // Check and set the Function or Subroutine flag on symbol; false on error.
5398 bool ResolveNamesVisitor::SetProcFlag(
5399 const parser::Name &name, Symbol &symbol, Symbol::Flag flag) {
5400 if (symbol.test(Symbol::Flag::Function) && flag == Symbol::Flag::Subroutine) {
5402 name, symbol, "Cannot call function '%s' like a subroutine"_err_en_US);
5404 } else if (symbol.test(Symbol::Flag::Subroutine) &&
5405 flag == Symbol::Flag::Function) {
5407 name, symbol, "Cannot call subroutine '%s' like a function"_err_en_US);
5409 } else if (symbol.has<ProcEntityDetails>()) {
5410 symbol.set(flag); // in case it hasn't been set yet
5411 if (flag == Symbol::Flag::Function) {
5412 ApplyImplicitRules(symbol);
5414 } else if (symbol.GetType() && flag == Symbol::Flag::Subroutine) {
5416 name, symbol, "Cannot call function '%s' like a subroutine"_err_en_US);
5421 bool ModuleVisitor::Pre(const parser::AccessStmt &x) {
5422 Attr accessAttr{AccessSpecToAttr(std::get<parser::AccessSpec>(x.t))};
5423 if (currScope().kind() != Scope::Kind::Module) {
5424 Say(currStmtSource().value(),
5425 "%s statement may only appear in the specification part of a module"_err_en_US,
5426 EnumToString(accessAttr));
5429 const auto &accessIds{std::get<std::list<parser::AccessId>>(x.t)};
5430 if (accessIds.empty()) {
5431 if (prevAccessStmt_) {
5432 Say("The default accessibility of this module has already been declared"_err_en_US)
5433 .Attach(*prevAccessStmt_, "Previous declaration"_en_US);
5435 prevAccessStmt_ = currStmtSource();
5436 defaultAccess_ = accessAttr;
5438 for (const auto &accessId : accessIds) {
5441 [=](const parser::Name &y) {
5442 Resolve(y, SetAccess(y.source, accessAttr));
5444 [=](const Indirection<parser::GenericSpec> &y) {
5445 auto info{GenericSpecInfo{y.value()}};
5446 const auto &symbolName{info.symbolName()};
5447 if (auto *symbol{info.FindInScope(context(), currScope())}) {
5448 info.Resolve(&SetAccess(symbolName, accessAttr, symbol));
5449 } else if (info.kind().IsName()) {
5450 info.Resolve(&SetAccess(symbolName, accessAttr));
5452 Say(symbolName, "Generic spec '%s' not found"_err_en_US);
5462 // Set the access specification for this symbol.
5463 Symbol &ModuleVisitor::SetAccess(
5464 const SourceName &name, Attr attr, Symbol *symbol) {
5466 symbol = &MakeSymbol(name);
5468 Attrs &attrs{symbol->attrs()};
5469 if (attrs.HasAny({Attr::PUBLIC, Attr::PRIVATE})) {
5470 // PUBLIC/PRIVATE already set: make it a fatal error if it changed
5471 Attr prev = attrs.test(Attr::PUBLIC) ? Attr::PUBLIC : Attr::PRIVATE;
5472 auto msg{IsDefinedOperator(name)
5473 ? "The accessibility of operator '%s' has already been specified as %s"_en_US
5474 : "The accessibility of '%s' has already been specified as %s"_en_US};
5475 Say(name, WithIsFatal(msg, attr != prev), name, EnumToString(prev));
5482 static bool NeedsExplicitType(const Symbol &symbol) {
5483 if (symbol.has<UnknownDetails>()) {
5485 } else if (const auto *details{symbol.detailsIf<EntityDetails>()}) {
5486 return !details->type();
5487 } else if (const auto *details{symbol.detailsIf<ObjectEntityDetails>()}) {
5488 return !details->type();
5489 } else if (const auto *details{symbol.detailsIf<ProcEntityDetails>()}) {
5490 return !details->interface().symbol() && !details->interface().type();
5496 bool ResolveNamesVisitor::Pre(const parser::SpecificationPart &x) {
5497 Walk(std::get<0>(x.t));
5498 Walk(std::get<1>(x.t));
5499 Walk(std::get<2>(x.t));
5500 Walk(std::get<3>(x.t));
5501 const std::list<parser::DeclarationConstruct> &decls{std::get<4>(x.t)};
5502 for (const auto &decl : decls) {
5503 if (const auto *spec{
5504 std::get_if<parser::SpecificationConstruct>(&decl.u)}) {
5505 PreSpecificationConstruct(*spec);
5509 FinishSpecificationPart();
5513 // Initial processing on specification constructs, before visiting them.
5514 void ResolveNamesVisitor::PreSpecificationConstruct(
5515 const parser::SpecificationConstruct &spec) {
5518 [&](const Indirection<parser::DerivedTypeDef> &) {},
5519 [&](const parser::Statement<Indirection<parser::GenericStmt>> &y) {
5520 CreateGeneric(std::get<parser::GenericSpec>(y.statement.value().t));
5522 [&](const Indirection<parser::InterfaceBlock> &y) {
5523 const auto &stmt{std::get<parser::Statement<parser::InterfaceStmt>>(
5525 const auto *spec{std::get_if<std::optional<parser::GenericSpec>>(
5526 &stmt.statement.u)};
5527 if (spec && *spec) {
5528 CreateGeneric(**spec);
5531 [&](const auto &) {},
5536 void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) {
5537 auto info{GenericSpecInfo{x}};
5538 const SourceName &symbolName{info.symbolName()};
5539 if (IsLogicalConstant(context(), symbolName)) {
5541 "Logical constant '%s' may not be used as a defined operator"_err_en_US);
5544 GenericDetails genericDetails;
5545 if (Symbol * existing{info.FindInScope(context(), currScope())}) {
5546 if (existing->has<GenericDetails>()) {
5547 info.Resolve(existing);
5548 return; // already have generic, add to it
5550 Symbol &ultimate{existing->GetUltimate()};
5551 if (auto *ultimateDetails{ultimate.detailsIf<GenericDetails>()}) {
5552 genericDetails.CopyFrom(*ultimateDetails);
5553 } else if (ultimate.has<SubprogramDetails>() ||
5554 ultimate.has<SubprogramNameDetails>()) {
5555 genericDetails.set_specific(ultimate);
5556 } else if (ultimate.has<DerivedTypeDetails>()) {
5557 genericDetails.set_derivedType(ultimate);
5559 SayAlreadyDeclared(symbolName, *existing);
5561 EraseSymbol(*existing);
5563 info.Resolve(&MakeSymbol(symbolName, Attrs{}, std::move(genericDetails)));
5566 void ResolveNamesVisitor::FinishSpecificationPart() {
5567 badStmtFuncFound_ = false;
5569 bool inModule{currScope().kind() == Scope::Kind::Module};
5570 for (auto &pair : currScope()) {
5571 auto &symbol{*pair.second};
5572 if (NeedsExplicitType(symbol)) {
5573 ApplyImplicitRules(symbol);
5575 if (symbol.has<GenericDetails>()) {
5576 CheckGenericProcedures(symbol);
5578 if (inModule && symbol.attrs().test(Attr::EXTERNAL) &&
5579 !symbol.test(Symbol::Flag::Function)) {
5580 // in a module, external proc without return type is subroutine
5581 symbol.set(Symbol::Flag::Subroutine);
5584 currScope().InstantiateDerivedTypes(context());
5585 // TODO: what about instantiations in BLOCK?
5587 CheckCommonBlocks();
5588 CheckEquivalenceSets();
5591 void ResolveNamesVisitor::CheckImports() {
5592 auto &scope{currScope()};
5593 switch (scope.GetImportKind()) {
5594 case common::ImportKind::None: break;
5595 case common::ImportKind::All:
5596 // C8102: all entities in host must not be hidden
5597 for (const auto &pair : scope.parent()) {
5598 auto &name{pair.first};
5599 std::optional<SourceName> scopeName{scope.GetName()};
5600 if (!scopeName || name != *scopeName) {
5601 CheckImport(prevImportStmt_.value(), name);
5605 case common::ImportKind::Default:
5606 case common::ImportKind::Only:
5607 // C8102: entities named in IMPORT must not be hidden
5608 for (auto &name : scope.importNames()) {
5609 CheckImport(name, name);
5615 void ResolveNamesVisitor::CheckImport(
5616 const SourceName &location, const SourceName &name) {
5617 if (auto *symbol{FindInScope(currScope(), name)}) {
5618 Say(location, "'%s' from host is not accessible"_err_en_US, name)
5619 .Attach(symbol->name(), "'%s' is hidden by this entity"_en_US,
5624 bool ResolveNamesVisitor::Pre(const parser::ImplicitStmt &x) {
5625 return CheckNotInBlock("IMPLICIT") && // C1107
5626 ImplicitRulesVisitor::Pre(x);
5629 void ResolveNamesVisitor::Post(const parser::PointerObject &x) {
5632 [&](const parser::Name &x) { ResolveName(x); },
5633 [&](const parser::StructureComponent &x) {
5634 ResolveStructureComponent(x);
5639 void ResolveNamesVisitor::Post(const parser::AllocateObject &x) {
5642 [&](const parser::Name &x) { ResolveName(x); },
5643 [&](const parser::StructureComponent &x) {
5644 ResolveStructureComponent(x);
5650 bool ResolveNamesVisitor::Pre(const parser::PointerAssignmentStmt &x) {
5651 const auto &dataRef{std::get<parser::DataRef>(x.t)};
5652 const auto &bounds{std::get<parser::PointerAssignmentStmt::Bounds>(x.t)};
5653 const auto &expr{std::get<parser::Expr>(x.t)};
5654 ResolveDataRef(dataRef);
5656 // Resolve unrestricted specific intrinsic procedures as in "p => cos".
5657 if (const parser::Name * name{parser::Unwrap<parser::Name>(expr)}) {
5658 if (NameIsKnownOrIntrinsic(*name)) {
5665 void ResolveNamesVisitor::Post(const parser::Designator &x) {
5666 ResolveDesignator(x);
5669 void ResolveNamesVisitor::Post(const parser::ProcComponentRef &x) {
5670 ResolveStructureComponent(x.v.thing);
5672 void ResolveNamesVisitor::Post(const parser::TypeGuardStmt &x) {
5673 DeclTypeSpecVisitor::Post(x);
5674 ConstructVisitor::Post(x);
5676 bool ResolveNamesVisitor::Pre(const parser::StmtFunctionStmt &x) {
5677 CheckNotInBlock("STATEMENT FUNCTION"); // C1107
5678 if (HandleStmtFunction(x)) {
5681 // This is an array element assignment: resolve names of indices
5682 const auto &names{std::get<std::list<parser::Name>>(x.t)};
5683 for (auto &name : names) {
5690 bool ResolveNamesVisitor::Pre(const parser::DefinedOpName &x) {
5691 const parser::Name &name{x.v};
5692 if (FindSymbol(name)) {
5694 } else if (IsLogicalConstant(context(), name.source)) {
5696 "Logical constant '%s' may not be used as a defined operator"_err_en_US);
5698 // Resolved later in expression semantics
5699 MakePlaceholder(name, MiscDetails::Kind::TypeBoundDefinedOp);
5704 bool ResolveNamesVisitor::Pre(const parser::ProgramUnit &x) {
5705 auto root{ProgramTree::Build(x)};
5706 SetScope(context().globalScope());
5707 ResolveSpecificationParts(root);
5708 FinishSpecificationParts(root);
5709 ResolveExecutionParts(root);
5710 OmpAttributeVisitor{context(), *this}.Walk(x);
5714 // References to procedures need to record that their symbols are known
5715 // to be procedures, so that they don't get converted to objects by default.
5716 class ExecutionPartSkimmer {
5718 explicit ExecutionPartSkimmer(ResolveNamesVisitor &resolver)
5719 : resolver_{resolver} {}
5721 void Walk(const parser::ExecutionPart *exec) {
5723 parser::Walk(*exec, *this);
5727 template<typename A> bool Pre(const A &) { return true; }
5728 template<typename A> void Post(const A &) {}
5729 void Post(const parser::FunctionReference &fr) {
5730 resolver_.NoteExecutablePartCall(Symbol::Flag::Function, fr.v);
5732 void Post(const parser::CallStmt &cs) {
5733 resolver_.NoteExecutablePartCall(Symbol::Flag::Subroutine, cs.v);
5737 ResolveNamesVisitor &resolver_;
5740 // Build the scope tree and resolve names in the specification parts of this
5741 // node and its children
5742 void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) {
5743 if (!BeginScope(node)) {
5744 return; // an error prevented scope from being created
5746 Scope &scope{currScope()};
5747 node.set_scope(scope);
5750 [&](const auto *x) {
5757 // If this is a function, convert result to an object. This is to prevent the
5758 // result to be converted later to a function symbol if it is called inside
5760 // If the result is function pointer, then ConvertToObjectEntity will not
5761 // convert the result to an object, and calling the symbol inside the function
5762 // will result in calls to the result pointer.
5763 // A function cannot be called recursively if RESULT was not used to define a
5764 // distinct result name (15.6.2.2 point 4.).
5765 if (Symbol * symbol{scope.symbol()}) {
5766 if (auto *details{symbol->detailsIf<SubprogramDetails>()}) {
5767 if (details->isFunction()) {
5768 ConvertToObjectEntity(const_cast<Symbol &>(details->result()));
5772 if (node.IsModule()) {
5773 ApplyDefaultAccess();
5775 for (auto &child : node.children()) {
5776 ResolveSpecificationParts(child);
5778 ExecutionPartSkimmer{*this}.Walk(node.exec());
5780 // Ensure that every object entity has a type.
5781 for (auto &pair : *node.scope()) {
5782 ApplyImplicitRules(*pair.second);
5786 // Add SubprogramNameDetails symbols for contained subprograms
5787 void ResolveNamesVisitor::AddSubpNames(const ProgramTree &node) {
5789 node.IsModule() ? SubprogramKind::Module : SubprogramKind::Internal};
5790 for (const auto &child : node.children()) {
5791 auto &symbol{MakeSymbol(child.name(), SubprogramNameDetails{kind})};
5792 symbol.set(child.GetSubpFlag());
5796 // Push a new scope for this node or return false on error.
5797 bool ResolveNamesVisitor::BeginScope(const ProgramTree &node) {
5798 switch (node.GetKind()) {
5799 SWITCH_COVERS_ALL_CASES
5800 case ProgramTree::Kind::Program:
5801 PushScope(Scope::Kind::MainProgram,
5802 &MakeSymbol(node.name(), MainProgramDetails{}));
5804 case ProgramTree::Kind::Function:
5805 case ProgramTree::Kind::Subroutine:
5806 return BeginSubprogram(
5807 node.name(), node.GetSubpFlag(), node.HasModulePrefix());
5808 case ProgramTree::Kind::MpSubprogram: return BeginMpSubprogram(node.name());
5809 case ProgramTree::Kind::Module: BeginModule(node.name(), false); return true;
5810 case ProgramTree::Kind::Submodule:
5811 return BeginSubmodule(node.name(), node.GetParentId());
5812 case ProgramTree::Kind::BlockData:
5813 PushBlockDataScope(node.name());
5818 // Some analyses and checks, such as the processing of initializers of
5819 // pointers, are deferred until all of the pertinent specification parts
5820 // have been visited. This deferred processing enables the use of forward
5821 // references in these circumstances.
5822 class DeferredCheckVisitor {
5824 explicit DeferredCheckVisitor(ResolveNamesVisitor &resolver)
5825 : resolver_{resolver} {}
5827 template<typename A> void Walk(const A &x) { parser::Walk(x, *this); }
5829 template<typename A> bool Pre(const A &) { return true; }
5830 template<typename A> void Post(const A &) {}
5832 void Post(const parser::DerivedTypeStmt &x) {
5833 const auto &name{std::get<parser::Name>(x.t)};
5834 if (Symbol * symbol{name.symbol}) {
5835 if (Scope * scope{symbol->scope()}) {
5836 if (scope->IsDerivedType()) {
5837 resolver_.PushScope(*scope);
5838 pushedScope_ = true;
5843 void Post(const parser::EndTypeStmt &) {
5845 resolver_.PopScope();
5846 pushedScope_ = false;
5850 void Post(const parser::ProcInterface &pi) {
5851 if (const auto *name{std::get_if<parser::Name>(&pi.u)}) {
5852 resolver_.CheckExplicitInterface(*name);
5855 bool Pre(const parser::EntityDecl &decl) {
5856 Init(std::get<parser::Name>(decl.t),
5857 std::get<std::optional<parser::Initialization>>(decl.t));
5860 bool Pre(const parser::ComponentDecl &decl) {
5861 Init(std::get<parser::Name>(decl.t),
5862 std::get<std::optional<parser::Initialization>>(decl.t));
5865 bool Pre(const parser::ProcDecl &decl) {
5866 if (const auto &init{
5867 std::get<std::optional<parser::ProcPointerInit>>(decl.t)}) {
5868 resolver_.PointerInitialization(std::get<parser::Name>(decl.t), *init);
5872 void Post(const parser::TypeBoundProcedureStmt::WithInterface &tbps) {
5873 resolver_.CheckExplicitInterface(tbps.interfaceName);
5875 void Post(const parser::TypeBoundProcedureStmt::WithoutInterface &tbps) {
5877 resolver_.CheckBindings(tbps);
5882 void Init(const parser::Name &name,
5883 const std::optional<parser::Initialization> &init) {
5885 if (const auto *target{
5886 std::get_if<parser::InitialDataTarget>(&init->u)}) {
5887 resolver_.PointerInitialization(name, *target);
5892 ResolveNamesVisitor &resolver_;
5893 bool pushedScope_{false};
5896 bool OmpAttributeVisitor::Pre(const parser::OpenMPBlockConstruct &x) {
5897 const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)};
5898 const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)};
5899 switch (beginDir.v) {
5900 case parser::OmpBlockDirective::Directive::Master:
5901 PushContext(beginDir.source, OmpDirective::MASTER);
5903 case parser::OmpBlockDirective::Directive::Ordered:
5904 PushContext(beginDir.source, OmpDirective::ORDERED);
5906 case parser::OmpBlockDirective::Directive::Parallel:
5907 PushContext(beginDir.source, OmpDirective::PARALLEL);
5909 case parser::OmpBlockDirective::Directive::Single:
5910 PushContext(beginDir.source, OmpDirective::SINGLE);
5912 case parser::OmpBlockDirective::Directive::Target:
5913 PushContext(beginDir.source, OmpDirective::TARGET);
5915 case parser::OmpBlockDirective::Directive::TargetData:
5916 PushContext(beginDir.source, OmpDirective::TARGET_DATA);
5918 case parser::OmpBlockDirective::Directive::Task:
5919 PushContext(beginDir.source, OmpDirective::TASK);
5921 case parser::OmpBlockDirective::Directive::Teams:
5922 PushContext(beginDir.source, OmpDirective::TEAMS);
5924 case parser::OmpBlockDirective::Directive::Workshare:
5925 PushContext(beginDir.source, OmpDirective::WORKSHARE);
5931 ClearDataSharingAttributeObjects();
5935 bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) {
5936 const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t)};
5937 const auto &beginDir{std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
5938 switch (beginDir.v) {
5939 case parser::OmpLoopDirective::Directive::Distribute:
5940 PushContext(beginDir.source, OmpDirective::DISTRIBUTE);
5942 case parser::OmpLoopDirective::Directive::Do:
5943 PushContext(beginDir.source, OmpDirective::DO);
5945 case parser::OmpLoopDirective::Directive::DoSimd:
5946 PushContext(beginDir.source, OmpDirective::DO_SIMD);
5948 case parser::OmpLoopDirective::Directive::ParallelDo:
5949 PushContext(beginDir.source, OmpDirective::PARALLEL_DO);
5951 case parser::OmpLoopDirective::Directive::ParallelDoSimd:
5952 PushContext(beginDir.source, OmpDirective::PARALLEL_DO_SIMD);
5954 case parser::OmpLoopDirective::Directive::Simd:
5955 PushContext(beginDir.source, OmpDirective::SIMD);
5957 case parser::OmpLoopDirective::Directive::Taskloop:
5958 PushContext(beginDir.source, OmpDirective::TASKLOOP);
5960 case parser::OmpLoopDirective::Directive::TaskloopSimd:
5961 PushContext(beginDir.source, OmpDirective::TASKLOOP_SIMD);
5967 ClearDataSharingAttributeObjects();
5971 bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionsConstruct &x) {
5972 const auto &beginSectionsDir{
5973 std::get<parser::OmpBeginSectionsDirective>(x.t)};
5974 const auto &beginDir{
5975 std::get<parser::OmpSectionsDirective>(beginSectionsDir.t)};
5976 switch (beginDir.v) {
5977 case parser::OmpSectionsDirective::Directive::ParallelSections:
5978 PushContext(beginDir.source, OmpDirective::PARALLEL_SECTIONS);
5980 case parser::OmpSectionsDirective::Directive::Sections:
5981 PushContext(beginDir.source, OmpDirective::SECTIONS);
5985 ClearDataSharingAttributeObjects();
5989 bool OmpAttributeVisitor::Pre(const parser::OpenMPThreadprivate &x) {
5990 PushContext(x.source, OmpDirective::THREADPRIVATE);
5991 const auto &list{std::get<parser::OmpObjectList>(x.t)};
5992 ResolveOmpObjectList(list, Symbol::Flag::OmpThreadprivate);
5996 void OmpAttributeVisitor::Post(const parser::OmpDefaultClause &x) {
5997 if (!ompContext_.empty()) {
5999 case parser::OmpDefaultClause::Type::Private:
6000 SetContextDefaultDSA(Symbol::Flag::OmpPrivate);
6002 case parser::OmpDefaultClause::Type::Firstprivate:
6003 SetContextDefaultDSA(Symbol::Flag::OmpFirstPrivate);
6005 case parser::OmpDefaultClause::Type::Shared:
6006 SetContextDefaultDSA(Symbol::Flag::OmpShared);
6008 case parser::OmpDefaultClause::Type::None:
6009 SetContextDefaultDSA(Symbol::Flag::OmpNone);
6015 // For OpenMP constructs, check all the data-refs within the constructs
6016 // and adjust the symbol for each Name if necessary
6017 void OmpAttributeVisitor::Post(const parser::Name &name) {
6018 auto *symbol{name.symbol};
6019 if (symbol && !ompContext_.empty() && GetContext().withinConstruct) {
6020 if (!symbol->owner().IsDerivedType() && !symbol->has<ProcEntityDetails>() &&
6021 !IsObjectWithDSA(*symbol)) {
6022 // TODO: create a separate function to go through the rules for
6023 // predetermined, explicitly determined, and implicitly
6024 // determined data-sharing attributes (2.15.1.1).
6025 if (Symbol * found{currScope().FindSymbol(name.source)}) {
6026 if (IsObjectWithDSA(*found)) {
6027 name.symbol = found; // adjust the symbol within region
6028 } else if (GetContext().defaultDSA == Symbol::Flag::OmpNone) {
6029 context_.Say(name.source,
6030 "The DEFAULT(NONE) clause requires that '%s' must be listed in "
6031 "a data-sharing attribute clause"_err_en_US,
6036 } // within OpenMP construct
6039 bool OmpAttributeVisitor::HasDataSharingAttributeObject(const Symbol &object) {
6040 auto it{dataSharingAttributeObjects_.find(object)};
6041 return it != dataSharingAttributeObjects_.end();
6044 Symbol *OmpAttributeVisitor::ResolveOmpCommonBlockName(
6045 const parser::Name *name) {
6047 ? GetContext().scope.parent().FindCommonBlock(name->source)
6049 name->symbol = prev;
6056 void OmpAttributeVisitor::ResolveOmpObjectList(
6057 const parser::OmpObjectList &ompObjectList, Symbol::Flag ompFlag) {
6058 for (const auto &ompObject : ompObjectList.v) {
6059 ResolveOmpObject(ompObject, ompFlag);
6063 void OmpAttributeVisitor::ResolveOmpObject(
6064 const parser::OmpObject &ompObject, Symbol::Flag ompFlag) {
6067 [&](const parser::Designator &designator) {
6068 if (const auto *name{GetDesignatorNameIfDataRef(designator)}) {
6069 if (auto *symbol{ResolveOmp(*name, ompFlag)}) {
6070 AddToContextObjectWithDSA(*symbol, ompFlag);
6071 if (dataSharingAttributeFlags.test(ompFlag)) {
6072 CheckMultipleAppearances(*name, *symbol, ompFlag);
6075 } else if (const auto *designatorName{
6076 resolver_.ResolveDesignator(designator)};
6077 designatorName->symbol) {
6078 // Array sections to be changed to substrings as needed
6079 if (AnalyzeExpr(context_, designator)) {
6080 if (std::holds_alternative<parser::Substring>(designator.u)) {
6081 context_.Say(designator.source,
6082 "Substrings are not allowed on OpenMP "
6083 "directives or clauses"_err_en_US);
6086 // other checks, more TBD
6087 if (const auto *details{designatorName->symbol
6088 ->detailsIf<ObjectEntityDetails>()}) {
6089 if (details->IsArray()) {
6090 // TODO: check Array Sections
6091 } else if (designatorName->symbol->owner().IsDerivedType()) {
6092 // TODO: check Structure Component
6097 [&](const parser::Name &name) { // common block
6098 if (auto *symbol{ResolveOmpCommonBlockName(&name)}) {
6099 CheckMultipleAppearances(
6100 name, *symbol, Symbol::Flag::OmpCommonBlock);
6101 // 2.15.3 When a named common block appears in a list, it has the
6102 // same meaning as if every explicit member of the common block
6103 // appeared in the list
6104 for (const Symbol &object :
6105 symbol->get<CommonBlockDetails>().objects()) {
6106 Symbol &mutableObject{const_cast<Symbol &>(object)};
6107 if (auto *resolvedObject{ResolveOmp(mutableObject, ompFlag)}) {
6108 AddToContextObjectWithDSA(*resolvedObject, ompFlag);
6112 context_.Say(name.source, // 2.15.3
6113 "COMMON block must be declared in the same scoping unit "
6114 "in which the OpenMP directive or clause appears"_err_en_US);
6121 Symbol *OmpAttributeVisitor::ResolveOmp(
6122 const parser::Name &name, Symbol::Flag ompFlag) {
6123 if (ompFlagsRequireNewSymbol.test(ompFlag)) {
6124 return DeclarePrivateAccessEntity(name, ompFlag);
6126 return DeclareOrMarkOtherAccessEntity(name, ompFlag);
6130 Symbol *OmpAttributeVisitor::ResolveOmp(Symbol &symbol, Symbol::Flag ompFlag) {
6131 if (ompFlagsRequireNewSymbol.test(ompFlag)) {
6132 return DeclarePrivateAccessEntity(symbol, ompFlag);
6134 return DeclareOrMarkOtherAccessEntity(symbol, ompFlag);
6138 Symbol *OmpAttributeVisitor::DeclarePrivateAccessEntity(
6139 const parser::Name &name, Symbol::Flag ompFlag) {
6141 return nullptr; // not resolved by Name Resolution step, do nothing
6143 name.symbol = DeclarePrivateAccessEntity(*name.symbol, ompFlag);
6147 Symbol *OmpAttributeVisitor::DeclarePrivateAccessEntity(
6148 Symbol &object, Symbol::Flag ompFlag) {
6149 if (object.owner() != currScope()) {
6150 auto &symbol{MakeAssocSymbol(object.name(), object)};
6151 symbol.set(ompFlag);
6154 object.set(ompFlag);
6159 Symbol *OmpAttributeVisitor::DeclareOrMarkOtherAccessEntity(
6160 const parser::Name &name, Symbol::Flag ompFlag) {
6161 Symbol *prev{currScope().FindSymbol(name.source)};
6162 if (!name.symbol || !prev) {
6164 } else if (prev != name.symbol) {
6167 return DeclareOrMarkOtherAccessEntity(*prev, ompFlag);
6170 Symbol *OmpAttributeVisitor::DeclareOrMarkOtherAccessEntity(
6171 Symbol &object, Symbol::Flag ompFlag) {
6172 if (ompFlagsRequireMark.test(ompFlag)) {
6173 object.set(ompFlag);
6178 static bool WithMultipleAppearancesException(
6179 const Symbol &symbol, Symbol::Flag ompFlag) {
6180 return (ompFlag == Symbol::Flag::OmpFirstPrivate &&
6181 symbol.test(Symbol::Flag::OmpLastPrivate)) ||
6182 (ompFlag == Symbol::Flag::OmpLastPrivate &&
6183 symbol.test(Symbol::Flag::OmpFirstPrivate));
6186 void OmpAttributeVisitor::CheckMultipleAppearances(
6187 const parser::Name &name, const Symbol &symbol, Symbol::Flag ompFlag) {
6188 const auto *target{&symbol};
6189 if (ompFlagsRequireNewSymbol.test(ompFlag)) {
6190 if (const auto *details{symbol.detailsIf<HostAssocDetails>()}) {
6191 target = &details->symbol();
6194 if (HasDataSharingAttributeObject(*target) &&
6195 !WithMultipleAppearancesException(symbol, ompFlag)) {
6196 context_.Say(name.source,
6197 "'%s' appears in more than one data-sharing clause "
6198 "on the same OpenMP directive"_err_en_US,
6201 AddDataSharingAttributeObject(*target);
6205 // Perform checks and completions that need to happen after all of
6206 // the specification parts but before any of the execution parts.
6207 void ResolveNamesVisitor::FinishSpecificationParts(const ProgramTree &node) {
6208 if (!node.scope()) {
6209 return; // error occurred creating scope
6211 SetScope(*node.scope());
6212 // The initializers of pointers, pointer components, and non-deferred
6213 // type-bound procedure bindings have not yet been traversed.
6214 // We do that now, when any (formerly) forward references that appear
6215 // in those initializers will resolve to the right symbols.
6216 DeferredCheckVisitor{*this}.Walk(node.spec());
6217 DeferredCheckVisitor{*this}.Walk(node.exec()); // for BLOCK
6218 for (Scope &childScope : currScope().children()) {
6219 if (childScope.IsDerivedType() && !childScope.symbol()) {
6220 FinishDerivedTypeInstantiation(childScope);
6223 for (const auto &child : node.children()) {
6224 FinishSpecificationParts(child);
6228 // Fold object pointer initializer designators with the actual
6229 // type parameter values of a particular instantiation.
6230 void ResolveNamesVisitor::FinishDerivedTypeInstantiation(Scope &scope) {
6231 CHECK(scope.IsDerivedType() && !scope.symbol());
6232 if (DerivedTypeSpec * spec{scope.derivedTypeSpec()}) {
6233 spec->Instantiate(currScope(), context());
6234 const Symbol &origTypeSymbol{spec->typeSymbol()};
6235 if (const Scope * origTypeScope{origTypeSymbol.scope()}) {
6236 CHECK(origTypeScope->IsDerivedType() &&
6237 origTypeScope->symbol() == &origTypeSymbol);
6238 auto &foldingContext{GetFoldingContext()};
6239 auto restorer{foldingContext.WithPDTInstance(*spec)};
6240 for (auto &pair : scope) {
6241 Symbol &comp{*pair.second};
6242 const Symbol &origComp{DEREF(FindInScope(*origTypeScope, comp.name()))};
6243 if (IsPointer(comp)) {
6244 if (auto *details{comp.detailsIf<ObjectEntityDetails>()}) {
6245 auto origDetails{origComp.get<ObjectEntityDetails>()};
6246 if (const MaybeExpr & init{origDetails.init()}) {
6247 SomeExpr newInit{*init};
6249 evaluate::Fold(foldingContext, std::move(newInit))};
6250 details->set_init(std::move(folded));
6259 // Resolve names in the execution part of this node and its children
6260 void ResolveNamesVisitor::ResolveExecutionParts(const ProgramTree &node) {
6261 if (!node.scope()) {
6262 return; // error occurred creating scope
6264 SetScope(*node.scope());
6265 if (const auto *exec{node.exec()}) {
6268 PopScope(); // converts unclassified entities into objects
6269 for (const auto &child : node.children()) {
6270 ResolveExecutionParts(child);
6274 void ResolveNamesVisitor::Post(const parser::Program &) {
6275 // ensure that all temps were deallocated
6277 CHECK(!GetDeclTypeSpec());
6280 bool ResolveNames(SemanticsContext &context, const parser::Program &program) {
6281 ResolveNamesVisitor{context}.Walk(program);
6282 return !context.AnyFatalError();