1 //===-- lib/Semantics/resolve-names.cpp -----------------------------------===//
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //===----------------------------------------------------------------------===//
8 #include "resolve-names.h"
9 #include "assignment.h"
10 #include "definable.h"
12 #include "pointer-assignment.h"
13 #include "program-tree.h"
14 #include "resolve-directives.h"
15 #include "resolve-names-utils.h"
16 #include "rewrite-parse-tree.h"
17 #include "flang/Common/Fortran.h"
18 #include "flang/Common/default-kinds.h"
19 #include "flang/Common/indirection.h"
20 #include "flang/Common/restorer.h"
21 #include "flang/Common/visit.h"
22 #include "flang/Evaluate/characteristics.h"
23 #include "flang/Evaluate/check-expression.h"
24 #include "flang/Evaluate/common.h"
25 #include "flang/Evaluate/fold-designator.h"
26 #include "flang/Evaluate/fold.h"
27 #include "flang/Evaluate/intrinsics.h"
28 #include "flang/Evaluate/tools.h"
29 #include "flang/Evaluate/type.h"
30 #include "flang/Parser/parse-tree-visitor.h"
31 #include "flang/Parser/parse-tree.h"
32 #include "flang/Parser/tools.h"
33 #include "flang/Semantics/attr.h"
34 #include "flang/Semantics/expression.h"
35 #include "flang/Semantics/scope.h"
36 #include "flang/Semantics/semantics.h"
37 #include "flang/Semantics/symbol.h"
38 #include "flang/Semantics/tools.h"
39 #include "flang/Semantics/type.h"
40 #include "llvm/Support/raw_ostream.h"
46 namespace Fortran::semantics
{
48 using namespace parser::literals
;
50 template <typename T
> using Indirection
= common::Indirection
<T
>;
51 using Message
= parser::Message
;
52 using Messages
= parser::Messages
;
53 using MessageFixedText
= parser::MessageFixedText
;
54 using MessageFormattedText
= parser::MessageFormattedText
;
56 class ResolveNamesVisitor
;
59 // ImplicitRules maps initial character of identifier to the DeclTypeSpec
60 // representing the implicit type; std::nullopt if none.
61 // It also records the presence of IMPLICIT NONE statements.
62 // When inheritFromParent is set, defaults come from the parent rules.
65 ImplicitRules(SemanticsContext
&context
, ImplicitRules
*parent
)
66 : parent_
{parent
}, context_
{context
} {
67 inheritFromParent_
= parent
!= nullptr;
69 bool isImplicitNoneType() const;
70 bool isImplicitNoneExternal() const;
71 void set_isImplicitNoneType(bool x
) { isImplicitNoneType_
= x
; }
72 void set_isImplicitNoneExternal(bool x
) { isImplicitNoneExternal_
= x
; }
73 void set_inheritFromParent(bool x
) { inheritFromParent_
= x
; }
74 // Get the implicit type for this name. May be null.
75 const DeclTypeSpec
*GetType(
76 SourceName
, bool respectImplicitNone
= true) const;
77 // Record the implicit type for the range of characters [fromLetter,
79 void SetTypeMapping(const DeclTypeSpec
&type
, parser::Location fromLetter
,
80 parser::Location toLetter
);
83 static char Incr(char ch
);
85 ImplicitRules
*parent_
;
86 SemanticsContext
&context_
;
87 bool inheritFromParent_
{false}; // look in parent if not specified here
88 bool isImplicitNoneType_
{
89 context_
.IsEnabled(common::LanguageFeature::ImplicitNoneTypeAlways
)};
90 bool isImplicitNoneExternal_
{false};
91 // map_ contains the mapping between letters and types that were defined
92 // by the IMPLICIT statements of the related scope. It does not contain
93 // the default Fortran mappings nor the mapping defined in parents.
94 std::map
<char, common::Reference
<const DeclTypeSpec
>> map_
;
96 friend llvm::raw_ostream
&operator<<(
97 llvm::raw_ostream
&, const ImplicitRules
&);
98 friend void ShowImplicitRule(
99 llvm::raw_ostream
&, const ImplicitRules
&, char);
102 // scope -> implicit rules for that scope
103 using ImplicitRulesMap
= std::map
<const Scope
*, ImplicitRules
>;
105 // Track statement source locations and save messages.
106 class MessageHandler
{
108 MessageHandler() { DIE("MessageHandler: default-constructed"); }
109 explicit MessageHandler(SemanticsContext
&c
) : context_
{&c
} {}
110 Messages
&messages() { return context_
->messages(); };
111 const std::optional
<SourceName
> &currStmtSource() {
112 return context_
->location();
114 void set_currStmtSource(const std::optional
<SourceName
> &source
) {
115 context_
->set_location(source
);
118 // Emit a message associated with the current statement source.
119 Message
&Say(MessageFixedText
&&);
120 Message
&Say(MessageFormattedText
&&);
121 // Emit a message about a SourceName
122 Message
&Say(const SourceName
&, MessageFixedText
&&);
123 // Emit a formatted message associated with a source location.
124 template <typename
... A
>
125 Message
&Say(const SourceName
&source
, MessageFixedText
&&msg
, A
&&...args
) {
126 return context_
->Say(source
, std::move(msg
), std::forward
<A
>(args
)...);
130 SemanticsContext
*context_
;
133 // Inheritance graph for the parse tree visitation classes that follow:
136 // | + DeclTypeSpecVisitor
137 // | + ImplicitRulesVisitor
138 // | + ScopeHandler -----------+--+
139 // | + ModuleVisitor ========|==+
140 // | + InterfaceVisitor | |
141 // | +-+ SubprogramVisitor ==|==+
142 // + ArraySpecVisitor | |
143 // + DeclarationVisitor <--------+ |
144 // + ConstructVisitor |
145 // + ResolveNamesVisitor <------+
149 BaseVisitor() { DIE("BaseVisitor: default-constructed"); }
151 SemanticsContext
&c
, ResolveNamesVisitor
&v
, ImplicitRulesMap
&rules
)
152 : implicitRulesMap_
{&rules
}, this_
{&v
}, context_
{&c
}, messageHandler_
{c
} {
154 template <typename T
> void Walk(const T
&);
156 MessageHandler
&messageHandler() { return messageHandler_
; }
157 const std::optional
<SourceName
> &currStmtSource() {
158 return context_
->location();
160 SemanticsContext
&context() const { return *context_
; }
161 evaluate::FoldingContext
&GetFoldingContext() const {
162 return context_
->foldingContext();
165 const SourceName
&name
, std::optional
<Symbol::Flag
> flag
) const {
167 return context_
->intrinsics().IsIntrinsic(name
.ToString());
168 } else if (flag
== Symbol::Flag::Function
) {
169 return context_
->intrinsics().IsIntrinsicFunction(name
.ToString());
170 } else if (flag
== Symbol::Flag::Subroutine
) {
171 return context_
->intrinsics().IsIntrinsicSubroutine(name
.ToString());
173 DIE("expected Subroutine or Function flag");
177 bool InModuleFile() const { return GetFoldingContext().inModuleFile(); }
179 // Make a placeholder symbol for a Name that otherwise wouldn't have one.
180 // It is not in any scope and always has MiscDetails.
181 void MakePlaceholder(const parser::Name
&, MiscDetails::Kind
);
183 template <typename T
> common::IfNoLvalue
<T
, T
> FoldExpr(T
&&expr
) {
184 return evaluate::Fold(GetFoldingContext(), std::move(expr
));
187 template <typename T
> MaybeExpr
EvaluateExpr(const T
&expr
) {
188 return FoldExpr(AnalyzeExpr(*context_
, expr
));
191 template <typename T
>
192 MaybeExpr
EvaluateNonPointerInitializer(
193 const Symbol
&symbol
, const T
&expr
, parser::CharBlock source
) {
194 if (!context().HasError(symbol
)) {
195 if (auto maybeExpr
{AnalyzeExpr(*context_
, expr
)}) {
196 auto restorer
{GetFoldingContext().messages().SetLocation(source
)};
197 return evaluate::NonPointerInitializationExpr(
198 symbol
, std::move(*maybeExpr
), GetFoldingContext());
204 template <typename T
> MaybeIntExpr
EvaluateIntExpr(const T
&expr
) {
205 return semantics::EvaluateIntExpr(*context_
, expr
);
208 template <typename T
>
209 MaybeSubscriptIntExpr
EvaluateSubscriptIntExpr(const T
&expr
) {
210 if (MaybeIntExpr maybeIntExpr
{EvaluateIntExpr(expr
)}) {
211 return FoldExpr(evaluate::ConvertToType
<evaluate::SubscriptInteger
>(
212 std::move(*maybeIntExpr
)));
218 template <typename
... A
> Message
&Say(A
&&...args
) {
219 return messageHandler_
.Say(std::forward
<A
>(args
)...);
221 template <typename
... A
>
223 const parser::Name
&name
, MessageFixedText
&&text
, const A
&...args
) {
224 return messageHandler_
.Say(name
.source
, std::move(text
), args
...);
228 ImplicitRulesMap
*implicitRulesMap_
{nullptr};
231 ResolveNamesVisitor
*this_
;
232 SemanticsContext
*context_
;
233 MessageHandler messageHandler_
;
236 // Provide Post methods to collect attributes into a member variable.
237 class AttrsVisitor
: public virtual BaseVisitor
{
239 bool BeginAttrs(); // always returns true
242 bool SetPassNameOn(Symbol
&);
243 void SetBindNameOn(Symbol
&);
244 void Post(const parser::LanguageBindingSpec
&);
245 bool Pre(const parser::IntentSpec
&);
246 bool Pre(const parser::Pass
&);
248 bool CheckAndSet(Attr
);
250 // Simple case: encountering CLASSNAME causes ATTRNAME to be set.
251 #define HANDLE_ATTR_CLASS(CLASSNAME, ATTRNAME) \
252 bool Pre(const parser::CLASSNAME &) { \
253 CheckAndSet(Attr::ATTRNAME); \
256 HANDLE_ATTR_CLASS(PrefixSpec::Elemental
, ELEMENTAL
)
257 HANDLE_ATTR_CLASS(PrefixSpec::Impure
, IMPURE
)
258 HANDLE_ATTR_CLASS(PrefixSpec::Module
, MODULE
)
259 HANDLE_ATTR_CLASS(PrefixSpec::Non_Recursive
, NON_RECURSIVE
)
260 HANDLE_ATTR_CLASS(PrefixSpec::Pure
, PURE
)
261 HANDLE_ATTR_CLASS(PrefixSpec::Recursive
, RECURSIVE
)
262 HANDLE_ATTR_CLASS(TypeAttrSpec::BindC
, BIND_C
)
263 HANDLE_ATTR_CLASS(BindAttr::Deferred
, DEFERRED
)
264 HANDLE_ATTR_CLASS(BindAttr::Non_Overridable
, NON_OVERRIDABLE
)
265 HANDLE_ATTR_CLASS(Abstract
, ABSTRACT
)
266 HANDLE_ATTR_CLASS(Allocatable
, ALLOCATABLE
)
267 HANDLE_ATTR_CLASS(Asynchronous
, ASYNCHRONOUS
)
268 HANDLE_ATTR_CLASS(Contiguous
, CONTIGUOUS
)
269 HANDLE_ATTR_CLASS(External
, EXTERNAL
)
270 HANDLE_ATTR_CLASS(Intrinsic
, INTRINSIC
)
271 HANDLE_ATTR_CLASS(NoPass
, NOPASS
)
272 HANDLE_ATTR_CLASS(Optional
, OPTIONAL
)
273 HANDLE_ATTR_CLASS(Parameter
, PARAMETER
)
274 HANDLE_ATTR_CLASS(Pointer
, POINTER
)
275 HANDLE_ATTR_CLASS(Protected
, PROTECTED
)
276 HANDLE_ATTR_CLASS(Save
, SAVE
)
277 HANDLE_ATTR_CLASS(Target
, TARGET
)
278 HANDLE_ATTR_CLASS(Value
, VALUE
)
279 HANDLE_ATTR_CLASS(Volatile
, VOLATILE
)
280 #undef HANDLE_ATTR_CLASS
283 std::optional
<Attrs
> attrs_
;
285 Attr
AccessSpecToAttr(const parser::AccessSpec
&x
) {
287 case parser::AccessSpec::Kind::Public
:
289 case parser::AccessSpec::Kind::Private
:
290 return Attr::PRIVATE
;
292 llvm_unreachable("Switch covers all cases"); // suppress g++ warning
294 Attr
IntentSpecToAttr(const parser::IntentSpec
&x
) {
296 case parser::IntentSpec::Intent::In
:
297 return Attr::INTENT_IN
;
298 case parser::IntentSpec::Intent::Out
:
299 return Attr::INTENT_OUT
;
300 case parser::IntentSpec::Intent::InOut
:
301 return Attr::INTENT_INOUT
;
303 llvm_unreachable("Switch covers all cases"); // suppress g++ warning
307 bool IsDuplicateAttr(Attr
);
308 bool HaveAttrConflict(Attr
, Attr
, Attr
);
309 bool IsConflictingAttr(Attr
);
311 MaybeExpr bindName_
; // from BIND(C, NAME="...")
312 std::optional
<SourceName
> passName_
; // from PASS(...)
315 // Find and create types from declaration-type-spec nodes.
316 class DeclTypeSpecVisitor
: public AttrsVisitor
{
318 using AttrsVisitor::Post
;
319 using AttrsVisitor::Pre
;
320 void Post(const parser::IntrinsicTypeSpec::DoublePrecision
&);
321 void Post(const parser::IntrinsicTypeSpec::DoubleComplex
&);
322 void Post(const parser::DeclarationTypeSpec::ClassStar
&);
323 void Post(const parser::DeclarationTypeSpec::TypeStar
&);
324 bool Pre(const parser::TypeGuardStmt
&);
325 void Post(const parser::TypeGuardStmt
&);
326 void Post(const parser::TypeSpec
&);
328 // Walk the parse tree of a type spec and return the DeclTypeSpec for it.
329 template <typename T
>
330 const DeclTypeSpec
*ProcessTypeSpec(const T
&x
, bool allowForward
= false) {
331 auto restorer
{common::ScopedSet(state_
, State
{})};
332 set_allowForwardReferenceToDerivedType(allowForward
);
335 const auto *type
{GetDeclTypeSpec()};
342 bool expectDeclTypeSpec
{false}; // should see decl-type-spec only when true
343 const DeclTypeSpec
*declTypeSpec
{nullptr};
345 DerivedTypeSpec
*type
{nullptr};
346 DeclTypeSpec::Category category
{DeclTypeSpec::TypeDerived
};
348 bool allowForwardReferenceToDerivedType
{false};
351 bool allowForwardReferenceToDerivedType() const {
352 return state_
.allowForwardReferenceToDerivedType
;
354 void set_allowForwardReferenceToDerivedType(bool yes
) {
355 state_
.allowForwardReferenceToDerivedType
= yes
;
358 const DeclTypeSpec
*GetDeclTypeSpec();
359 void BeginDeclTypeSpec();
360 void EndDeclTypeSpec();
361 void SetDeclTypeSpec(const DeclTypeSpec
&);
362 void SetDeclTypeSpecCategory(DeclTypeSpec::Category
);
363 DeclTypeSpec::Category
GetDeclTypeSpecCategory() const {
364 return state_
.derived
.category
;
366 KindExpr
GetKindParamExpr(
367 TypeCategory
, const std::optional
<parser::KindSelector
> &);
368 void CheckForAbstractType(const Symbol
&typeSymbol
);
373 void MakeNumericType(TypeCategory
, int kind
);
376 // Visit ImplicitStmt and related parse tree nodes and updates implicit rules.
377 class ImplicitRulesVisitor
: public DeclTypeSpecVisitor
{
379 using DeclTypeSpecVisitor::Post
;
380 using DeclTypeSpecVisitor::Pre
;
381 using ImplicitNoneNameSpec
= parser::ImplicitStmt::ImplicitNoneNameSpec
;
383 void Post(const parser::ParameterStmt
&);
384 bool Pre(const parser::ImplicitStmt
&);
385 bool Pre(const parser::LetterSpec
&);
386 bool Pre(const parser::ImplicitSpec
&);
387 void Post(const parser::ImplicitSpec
&);
389 const DeclTypeSpec
*GetType(
390 SourceName name
, bool respectImplicitNoneType
= true) {
391 return implicitRules_
->GetType(name
, respectImplicitNoneType
);
393 bool isImplicitNoneType() const {
394 return implicitRules_
->isImplicitNoneType();
396 bool isImplicitNoneType(const Scope
&scope
) const {
397 return implicitRulesMap_
->at(&scope
).isImplicitNoneType();
399 bool isImplicitNoneExternal() const {
400 return implicitRules_
->isImplicitNoneExternal();
402 void set_inheritFromParent(bool x
) {
403 implicitRules_
->set_inheritFromParent(x
);
407 void BeginScope(const Scope
&);
408 void SetScope(const Scope
&);
411 // implicit rules in effect for current scope
412 ImplicitRules
*implicitRules_
{nullptr};
413 std::optional
<SourceName
> prevImplicit_
;
414 std::optional
<SourceName
> prevImplicitNone_
;
415 std::optional
<SourceName
> prevImplicitNoneType_
;
416 std::optional
<SourceName
> prevParameterStmt_
;
418 bool HandleImplicitNone(const std::list
<ImplicitNoneNameSpec
> &nameSpecs
);
421 // Track array specifications. They can occur in AttrSpec, EntityDecl,
422 // ObjectDecl, DimensionStmt, CommonBlockObject, or BasedPointerStmt.
423 // 1. INTEGER, DIMENSION(10) :: x
424 // 2. INTEGER :: x(10)
425 // 3. ALLOCATABLE :: x(:)
426 // 4. DIMENSION :: x(10)
428 // 6. BasedPointerStmt
429 class ArraySpecVisitor
: public virtual BaseVisitor
{
431 void Post(const parser::ArraySpec
&);
432 void Post(const parser::ComponentArraySpec
&);
433 void Post(const parser::CoarraySpec
&);
434 void Post(const parser::AttrSpec
&) { PostAttrSpec(); }
435 void Post(const parser::ComponentAttrSpec
&) { PostAttrSpec(); }
438 const ArraySpec
&arraySpec();
439 void set_arraySpec(const ArraySpec arraySpec
) { arraySpec_
= arraySpec
; }
440 const ArraySpec
&coarraySpec();
441 void BeginArraySpec();
443 void ClearArraySpec() { arraySpec_
.clear(); }
444 void ClearCoarraySpec() { coarraySpec_
.clear(); }
447 // arraySpec_/coarraySpec_ are populated from any ArraySpec/CoarraySpec
448 ArraySpec arraySpec_
;
449 ArraySpec coarraySpec_
;
450 // When an ArraySpec is under an AttrSpec or ComponentAttrSpec, it is moved
451 // into attrArraySpec_
452 ArraySpec attrArraySpec_
;
453 ArraySpec attrCoarraySpec_
;
458 // Manages a stack of function result information. We defer the processing
459 // of a type specification that appears in the prefix of a FUNCTION statement
460 // until the function result variable appears in the specification part
461 // or the end of the specification part. This allows for forward references
462 // in the type specification to resolve to local names.
463 class FuncResultStack
{
465 explicit FuncResultStack(ScopeHandler
&scopeHandler
)
466 : scopeHandler_
{scopeHandler
} {}
470 explicit FuncInfo(const Scope
&s
) : scope
{s
} {}
472 // Parse tree of the type specification in the FUNCTION prefix
473 const parser::DeclarationTypeSpec
*parsedType
{nullptr};
474 // Name of the function RESULT in the FUNCTION suffix, if any
475 const parser::Name
*resultName
{nullptr};
477 Symbol
*resultSymbol
{nullptr};
478 std::optional
<SourceName
> source
;
479 bool inFunctionStmt
{false}; // true between Pre/Post of FunctionStmt
482 // Completes the definition of the top function's result.
483 void CompleteFunctionResultType();
484 // Completes the definition of a symbol if it is the top function's result.
485 void CompleteTypeIfFunctionResult(Symbol
&);
487 FuncInfo
*Top() { return stack_
.empty() ? nullptr : &stack_
.back(); }
488 FuncInfo
&Push(const Scope
&scope
) { return stack_
.emplace_back(scope
); }
492 ScopeHandler
&scopeHandler_
;
493 std::vector
<FuncInfo
> stack_
;
496 // Manage a stack of Scopes
497 class ScopeHandler
: public ImplicitRulesVisitor
{
499 using ImplicitRulesVisitor::Post
;
500 using ImplicitRulesVisitor::Pre
;
502 Scope
&currScope() { return DEREF(currScope_
); }
503 // The enclosing host procedure if current scope is in an internal procedure
504 Scope
*GetHostProcedure();
505 // The innermost enclosing program unit scope, ignoring BLOCK and other
507 Scope
&InclusiveScope();
508 // The enclosing scope, skipping derived types.
509 Scope
&NonDerivedTypeScope();
511 // Create a new scope and push it on the scope stack.
512 void PushScope(Scope::Kind kind
, Symbol
*symbol
);
513 void PushScope(Scope
&scope
);
515 void SetScope(Scope
&);
517 template <typename T
> bool Pre(const parser::Statement
<T
> &x
) {
518 messageHandler().set_currStmtSource(x
.source
);
519 currScope_
->AddSourceRange(x
.source
);
522 template <typename T
> void Post(const parser::Statement
<T
> &) {
523 messageHandler().set_currStmtSource(std::nullopt
);
526 // Special messages: already declared; referencing symbol's declaration;
527 // about a type; two names & locations
528 void SayAlreadyDeclared(const parser::Name
&, Symbol
&);
529 void SayAlreadyDeclared(const SourceName
&, Symbol
&);
530 void SayAlreadyDeclared(const SourceName
&, const SourceName
&);
532 const parser::Name
&, Symbol
&, MessageFixedText
&&, Message
&&);
533 void SayWithDecl(const parser::Name
&, Symbol
&, MessageFixedText
&&);
534 void SayLocalMustBeVariable(const parser::Name
&, Symbol
&);
535 void SayDerivedType(const SourceName
&, MessageFixedText
&&, const Scope
&);
536 void Say2(const SourceName
&, MessageFixedText
&&, const SourceName
&,
537 MessageFixedText
&&);
539 const SourceName
&, MessageFixedText
&&, Symbol
&, MessageFixedText
&&);
541 const parser::Name
&, MessageFixedText
&&, Symbol
&, MessageFixedText
&&);
543 // Search for symbol by name in current, parent derived type, and
545 Symbol
*FindSymbol(const parser::Name
&);
546 Symbol
*FindSymbol(const Scope
&, const parser::Name
&);
547 // Search for name only in scope, not in enclosing scopes.
548 Symbol
*FindInScope(const Scope
&, const parser::Name
&);
549 Symbol
*FindInScope(const Scope
&, const SourceName
&);
550 template <typename T
> Symbol
*FindInScope(const T
&name
) {
551 return FindInScope(currScope(), name
);
553 // Search for name in a derived type scope and its parents.
554 Symbol
*FindInTypeOrParents(const Scope
&, const parser::Name
&);
555 Symbol
*FindInTypeOrParents(const parser::Name
&);
556 Symbol
*FindInScopeOrBlockConstructs(const Scope
&, SourceName
);
557 Symbol
*FindSeparateModuleProcedureInterface(const parser::Name
&);
558 void EraseSymbol(const parser::Name
&);
559 void EraseSymbol(const Symbol
&symbol
) { currScope().erase(symbol
.name()); }
560 // Make a new symbol with the name and attrs of an existing one
561 Symbol
&CopySymbol(const SourceName
&, const Symbol
&);
563 // Make symbols in the current or named scope
564 Symbol
&MakeSymbol(Scope
&, const SourceName
&, Attrs
);
565 Symbol
&MakeSymbol(const SourceName
&, Attrs
= Attrs
{});
566 Symbol
&MakeSymbol(const parser::Name
&, Attrs
= Attrs
{});
567 Symbol
&MakeHostAssocSymbol(const parser::Name
&, const Symbol
&);
569 template <typename D
>
570 common::IfNoLvalue
<Symbol
&, D
> MakeSymbol(
571 const parser::Name
&name
, D
&&details
) {
572 return MakeSymbol(name
, Attrs
{}, std::move(details
));
575 template <typename D
>
576 common::IfNoLvalue
<Symbol
&, D
> MakeSymbol(
577 const parser::Name
&name
, const Attrs
&attrs
, D
&&details
) {
578 return Resolve(name
, MakeSymbol(name
.source
, attrs
, std::move(details
)));
581 template <typename D
>
582 common::IfNoLvalue
<Symbol
&, D
> MakeSymbol(
583 const SourceName
&name
, const Attrs
&attrs
, D
&&details
) {
584 // Note: don't use FindSymbol here. If this is a derived type scope,
585 // we want to detect whether the name is already declared as a component.
586 auto *symbol
{FindInScope(name
)};
588 symbol
= &MakeSymbol(name
, attrs
);
589 symbol
->set_details(std::move(details
));
592 if constexpr (std::is_same_v
<DerivedTypeDetails
, D
>) {
593 if (auto *d
{symbol
->detailsIf
<GenericDetails
>()}) {
594 if (!d
->specific()) {
595 // derived type with same name as a generic
596 auto *derivedType
{d
->derivedType()};
599 &currScope().MakeSymbol(name
, attrs
, std::move(details
));
600 d
->set_derivedType(*derivedType
);
601 } else if (derivedType
->CanReplaceDetails(details
)) {
602 // was forward-referenced
603 CheckDuplicatedAttrs(name
, *symbol
, attrs
);
604 SetExplicitAttrs(*derivedType
, attrs
);
605 derivedType
->set_details(std::move(details
));
607 SayAlreadyDeclared(name
, *derivedType
);
613 if (symbol
->CanReplaceDetails(details
)) {
614 // update the existing symbol
615 CheckDuplicatedAttrs(name
, *symbol
, attrs
);
616 SetExplicitAttrs(*symbol
, attrs
);
617 if constexpr (std::is_same_v
<SubprogramDetails
, D
>) {
618 // Dummy argument defined by explicit interface?
619 details
.set_isDummy(IsDummy(*symbol
));
621 symbol
->set_details(std::move(details
));
623 } else if constexpr (std::is_same_v
<UnknownDetails
, D
>) {
624 CheckDuplicatedAttrs(name
, *symbol
, attrs
);
625 SetExplicitAttrs(*symbol
, attrs
);
628 if (!CheckPossibleBadForwardRef(*symbol
)) {
629 if (name
.empty() && symbol
->name().empty()) {
630 // report the error elsewhere
633 SayAlreadyDeclared(name
, *symbol
);
635 // replace the old symbol with a new one with correct details
636 EraseSymbol(*symbol
);
637 auto &result
{MakeSymbol(name
, attrs
, std::move(details
))};
638 context().SetError(result
);
643 void MakeExternal(Symbol
&);
645 // C815 duplicated attribute checking; returns false on error
646 bool CheckDuplicatedAttr(SourceName
, const Symbol
&, Attr
);
647 bool CheckDuplicatedAttrs(SourceName
, const Symbol
&, Attrs
);
649 void SetExplicitAttr(Symbol
&symbol
, Attr attr
) const {
650 symbol
.attrs().set(attr
);
651 symbol
.implicitAttrs().reset(attr
);
653 void SetExplicitAttrs(Symbol
&symbol
, Attrs attrs
) const {
654 symbol
.attrs() |= attrs
;
655 symbol
.implicitAttrs() &= ~attrs
;
657 void SetImplicitAttr(Symbol
&symbol
, Attr attr
) const {
658 symbol
.attrs().set(attr
);
659 symbol
.implicitAttrs().set(attr
);
663 FuncResultStack
&funcResultStack() { return funcResultStack_
; }
665 // Apply the implicit type rules to this symbol.
666 void ApplyImplicitRules(Symbol
&, bool allowForwardReference
= false);
667 bool ImplicitlyTypeForwardRef(Symbol
&);
668 void AcquireIntrinsicProcedureFlags(Symbol
&);
669 const DeclTypeSpec
*GetImplicitType(
670 Symbol
&, bool respectImplicitNoneType
= true);
671 void CheckEntryDummyUse(SourceName
, Symbol
*);
672 bool ConvertToObjectEntity(Symbol
&);
673 bool ConvertToProcEntity(Symbol
&);
675 const DeclTypeSpec
&MakeNumericType(
676 TypeCategory
, const std::optional
<parser::KindSelector
> &);
677 const DeclTypeSpec
&MakeNumericType(TypeCategory
, int);
678 const DeclTypeSpec
&MakeLogicalType(
679 const std::optional
<parser::KindSelector
> &);
680 const DeclTypeSpec
&MakeLogicalType(int);
681 void NotePossibleBadForwardRef(const parser::Name
&);
682 std::optional
<SourceName
> HadForwardRef(const Symbol
&) const;
683 bool CheckPossibleBadForwardRef(const Symbol
&);
685 bool inSpecificationPart_
{false};
686 bool inEquivalenceStmt_
{false};
688 // Some information is collected from a specification part for deferred
689 // processing in DeclarationPartVisitor functions (e.g., CheckSaveStmts())
690 // that are called by ResolveNamesVisitor::FinishSpecificationPart(). Since
691 // specification parts can nest (e.g., INTERFACE bodies), the collected
692 // information that is not contained in the scope needs to be packaged
694 struct SpecificationPartState
{
695 std::set
<SourceName
> forwardRefs
;
696 // Collect equivalence sets and process at end of specification part
697 std::vector
<const std::list
<parser::EquivalenceObject
> *> equivalenceSets
;
698 // Names of all common block objects in the scope
699 std::set
<SourceName
> commonBlockObjects
;
700 // Info about about SAVE statements and attributes in current scope
702 std::optional
<SourceName
> saveAll
; // "SAVE" without entity list
703 std::set
<SourceName
> entities
; // names of entities with save attr
704 std::set
<SourceName
> commons
; // names of common blocks with save attr
708 // Some declaration processing can and should be deferred to
709 // ResolveExecutionParts() to avoid prematurely creating implicitly-typed
710 // local symbols that should be host associations.
711 struct DeferredDeclarationState
{
712 // The content of each namelist group
713 std::list
<const parser::NamelistStmt::Group
*> namelistGroups
;
715 DeferredDeclarationState
*GetDeferredDeclarationState(bool add
= false) {
716 if (!add
&& deferred_
.find(&currScope()) == deferred_
.end()) {
719 return &deferred_
.emplace(&currScope(), DeferredDeclarationState
{})
725 Scope
*currScope_
{nullptr};
726 FuncResultStack funcResultStack_
{*this};
727 std::map
<Scope
*, DeferredDeclarationState
> deferred_
;
730 class ModuleVisitor
: public virtual ScopeHandler
{
732 bool Pre(const parser::AccessStmt
&);
733 bool Pre(const parser::Only
&);
734 bool Pre(const parser::Rename::Names
&);
735 bool Pre(const parser::Rename::Operators
&);
736 bool Pre(const parser::UseStmt
&);
737 void Post(const parser::UseStmt
&);
739 void BeginModule(const parser::Name
&, bool isSubmodule
);
740 bool BeginSubmodule(const parser::Name
&, const parser::ParentIdentifier
&);
741 void ApplyDefaultAccess();
742 Symbol
&AddGenericUse(GenericDetails
&, const SourceName
&, const Symbol
&);
743 void AddAndCheckExplicitIntrinsicUse(SourceName
, bool isIntrinsic
);
744 void ClearUseRenames() { useRenames_
.clear(); }
745 void ClearUseOnly() { useOnly_
.clear(); }
746 void ClearExplicitIntrinsicUses() {
747 explicitIntrinsicUses_
.clear();
748 explicitNonIntrinsicUses_
.clear();
752 // The default access spec for this module.
753 Attr defaultAccess_
{Attr::PUBLIC
};
754 // The location of the last AccessStmt without access-ids, if any.
755 std::optional
<SourceName
> prevAccessStmt_
;
756 // The scope of the module during a UseStmt
757 Scope
*useModuleScope_
{nullptr};
758 // Names that have appeared in a rename clause of a USE statement
759 std::set
<std::pair
<SourceName
, Scope
*>> useRenames_
;
760 // Names that have appeared in an ONLY clause of a USE statement
761 std::set
<std::pair
<SourceName
, Scope
*>> useOnly_
;
762 // Module names that have appeared in USE statements with explicit
763 // INTRINSIC or NON_INTRINSIC keywords
764 std::set
<SourceName
> explicitIntrinsicUses_
;
765 std::set
<SourceName
> explicitNonIntrinsicUses_
;
767 Symbol
&SetAccess(const SourceName
&, Attr attr
, Symbol
* = nullptr);
768 // A rename in a USE statement: local => use
769 struct SymbolRename
{
770 Symbol
*local
{nullptr};
771 Symbol
*use
{nullptr};
773 // Record a use from useModuleScope_ of use Name/Symbol as local Name/Symbol
774 SymbolRename
AddUse(const SourceName
&localName
, const SourceName
&useName
);
775 SymbolRename
AddUse(const SourceName
&, const SourceName
&, Symbol
*);
777 SourceName
, SourceName
, Symbol
&localSymbol
, const Symbol
&useSymbol
);
778 void AddUse(const GenericSpecInfo
&);
779 // If appropriate, erase a previously USE-associated symbol
780 void EraseRenamedSymbol(const Symbol
&);
781 // Record a name appearing in a USE rename clause
782 void AddUseRename(const SourceName
&name
) {
783 useRenames_
.emplace(std::make_pair(name
, useModuleScope_
));
785 bool IsUseRenamed(const SourceName
&name
) const {
786 return useRenames_
.find({name
, useModuleScope_
}) != useRenames_
.end();
788 // Record a name appearing in a USE ONLY clause
789 void AddUseOnly(const SourceName
&name
) {
790 useOnly_
.emplace(std::make_pair(name
, useModuleScope_
));
792 bool IsUseOnly(const SourceName
&name
) const {
793 return useOnly_
.find({name
, useModuleScope_
}) != useOnly_
.end();
795 Scope
*FindModule(const parser::Name
&, std::optional
<bool> isIntrinsic
,
796 Scope
*ancestor
= nullptr);
799 class InterfaceVisitor
: public virtual ScopeHandler
{
801 bool Pre(const parser::InterfaceStmt
&);
802 void Post(const parser::InterfaceStmt
&);
803 void Post(const parser::EndInterfaceStmt
&);
804 bool Pre(const parser::GenericSpec
&);
805 bool Pre(const parser::ProcedureStmt
&);
806 bool Pre(const parser::GenericStmt
&);
807 void Post(const parser::GenericStmt
&);
809 bool inInterfaceBlock() const;
810 bool isGeneric() const;
811 bool isAbstract() const;
814 Symbol
&GetGenericSymbol() { return DEREF(genericInfo_
.top().symbol
); }
815 // Add to generic the symbol for the subprogram with the same name
816 void CheckGenericProcedures(Symbol
&);
819 // A new GenericInfo is pushed for each interface block and generic stmt
821 GenericInfo(bool isInterface
, bool isAbstract
= false)
822 : isInterface
{isInterface
}, isAbstract
{isAbstract
} {}
823 bool isInterface
; // in interface block
824 bool isAbstract
; // in abstract interface block
825 Symbol
*symbol
{nullptr}; // the generic symbol being defined
827 std::stack
<GenericInfo
> genericInfo_
;
828 const GenericInfo
&GetGenericInfo() const { return genericInfo_
.top(); }
829 void SetGenericSymbol(Symbol
&symbol
) { genericInfo_
.top().symbol
= &symbol
; }
831 using ProcedureKind
= parser::ProcedureStmt::Kind
;
832 // mapping of generic to its specific proc names and kinds
833 std::multimap
<Symbol
*, std::pair
<const parser::Name
*, ProcedureKind
>>
836 void AddSpecificProcs(const std::list
<parser::Name
> &, ProcedureKind
);
837 void ResolveSpecificsInGeneric(Symbol
&generic
);
840 class SubprogramVisitor
: public virtual ScopeHandler
, public InterfaceVisitor
{
842 bool HandleStmtFunction(const parser::StmtFunctionStmt
&);
843 bool Pre(const parser::SubroutineStmt
&);
844 bool Pre(const parser::FunctionStmt
&);
845 void Post(const parser::FunctionStmt
&);
846 bool Pre(const parser::EntryStmt
&);
847 void Post(const parser::EntryStmt
&);
848 bool Pre(const parser::InterfaceBody::Subroutine
&);
849 void Post(const parser::InterfaceBody::Subroutine
&);
850 bool Pre(const parser::InterfaceBody::Function
&);
851 void Post(const parser::InterfaceBody::Function
&);
852 bool Pre(const parser::Suffix
&);
853 bool Pre(const parser::PrefixSpec
&);
855 bool BeginSubprogram(const parser::Name
&, Symbol::Flag
,
856 bool hasModulePrefix
= false,
857 const parser::LanguageBindingSpec
* = nullptr,
858 const ProgramTree::EntryStmtList
* = nullptr);
859 bool BeginMpSubprogram(const parser::Name
&);
860 void PushBlockDataScope(const parser::Name
&);
861 void EndSubprogram(std::optional
<parser::CharBlock
> stmtSource
= std::nullopt
,
862 const std::optional
<parser::LanguageBindingSpec
> * = nullptr,
863 const ProgramTree::EntryStmtList
* = nullptr);
866 // Set when we see a stmt function that is really an array element assignment
867 bool badStmtFuncFound_
{false};
870 // Edits an existing symbol created for earlier calls to a subprogram or ENTRY
871 // so that it can be replaced by a later definition.
872 bool HandlePreviousCalls(const parser::Name
&, Symbol
&, Symbol::Flag
);
873 void CheckExtantProc(const parser::Name
&, Symbol::Flag
);
874 // Create a subprogram symbol in the current scope and push a new scope.
875 Symbol
&PushSubprogramScope(const parser::Name
&, Symbol::Flag
,
876 const parser::LanguageBindingSpec
* = nullptr);
877 Symbol
*GetSpecificFromGeneric(const parser::Name
&);
878 Symbol
&PostSubprogramStmt();
879 void CreateDummyArgument(SubprogramDetails
&, const parser::Name
&);
880 void CreateEntry(const parser::EntryStmt
&stmt
, Symbol
&subprogram
);
881 void PostEntryStmt(const parser::EntryStmt
&stmt
);
882 void HandleLanguageBinding(Symbol
*,
883 std::optional
<parser::CharBlock
> stmtSource
,
884 const std::optional
<parser::LanguageBindingSpec
> *);
887 class DeclarationVisitor
: public ArraySpecVisitor
,
888 public virtual ScopeHandler
{
890 using ArraySpecVisitor::Post
;
891 using ScopeHandler::Post
;
892 using ScopeHandler::Pre
;
894 bool Pre(const parser::Initialization
&);
895 void Post(const parser::EntityDecl
&);
896 void Post(const parser::ObjectDecl
&);
897 void Post(const parser::PointerDecl
&);
898 bool Pre(const parser::BindStmt
&) { return BeginAttrs(); }
899 void Post(const parser::BindStmt
&) { EndAttrs(); }
900 bool Pre(const parser::BindEntity
&);
901 bool Pre(const parser::OldParameterStmt
&);
902 bool Pre(const parser::NamedConstantDef
&);
903 bool Pre(const parser::NamedConstant
&);
904 void Post(const parser::EnumDef
&);
905 bool Pre(const parser::Enumerator
&);
906 bool Pre(const parser::AccessSpec
&);
907 bool Pre(const parser::AsynchronousStmt
&);
908 bool Pre(const parser::ContiguousStmt
&);
909 bool Pre(const parser::ExternalStmt
&);
910 bool Pre(const parser::IntentStmt
&);
911 bool Pre(const parser::IntrinsicStmt
&);
912 bool Pre(const parser::OptionalStmt
&);
913 bool Pre(const parser::ProtectedStmt
&);
914 bool Pre(const parser::ValueStmt
&);
915 bool Pre(const parser::VolatileStmt
&);
916 bool Pre(const parser::AllocatableStmt
&) {
917 objectDeclAttr_
= Attr::ALLOCATABLE
;
920 void Post(const parser::AllocatableStmt
&) { objectDeclAttr_
= std::nullopt
; }
921 bool Pre(const parser::TargetStmt
&) {
922 objectDeclAttr_
= Attr::TARGET
;
925 void Post(const parser::TargetStmt
&) { objectDeclAttr_
= std::nullopt
; }
926 void Post(const parser::DimensionStmt::Declaration
&);
927 void Post(const parser::CodimensionDecl
&);
928 bool Pre(const parser::TypeDeclarationStmt
&) { return BeginDecl(); }
929 void Post(const parser::TypeDeclarationStmt
&);
930 void Post(const parser::IntegerTypeSpec
&);
931 void Post(const parser::IntrinsicTypeSpec::Real
&);
932 void Post(const parser::IntrinsicTypeSpec::Complex
&);
933 void Post(const parser::IntrinsicTypeSpec::Logical
&);
934 void Post(const parser::IntrinsicTypeSpec::Character
&);
935 void Post(const parser::CharSelector::LengthAndKind
&);
936 void Post(const parser::CharLength
&);
937 void Post(const parser::LengthSelector
&);
938 bool Pre(const parser::KindParam
&);
939 bool Pre(const parser::DeclarationTypeSpec::Type
&);
940 void Post(const parser::DeclarationTypeSpec::Type
&);
941 bool Pre(const parser::DeclarationTypeSpec::Class
&);
942 void Post(const parser::DeclarationTypeSpec::Class
&);
943 void Post(const parser::DeclarationTypeSpec::Record
&);
944 void Post(const parser::DerivedTypeSpec
&);
945 bool Pre(const parser::DerivedTypeDef
&);
946 bool Pre(const parser::DerivedTypeStmt
&);
947 void Post(const parser::DerivedTypeStmt
&);
948 bool Pre(const parser::TypeParamDefStmt
&) { return BeginDecl(); }
949 void Post(const parser::TypeParamDefStmt
&);
950 bool Pre(const parser::TypeAttrSpec::Extends
&);
951 bool Pre(const parser::PrivateStmt
&);
952 bool Pre(const parser::SequenceStmt
&);
953 bool Pre(const parser::ComponentDefStmt
&) { return BeginDecl(); }
954 void Post(const parser::ComponentDefStmt
&) { EndDecl(); }
955 void Post(const parser::ComponentDecl
&);
956 void Post(const parser::FillDecl
&);
957 bool Pre(const parser::ProcedureDeclarationStmt
&);
958 void Post(const parser::ProcedureDeclarationStmt
&);
959 bool Pre(const parser::DataComponentDefStmt
&); // returns false
960 bool Pre(const parser::ProcComponentDefStmt
&);
961 void Post(const parser::ProcComponentDefStmt
&);
962 bool Pre(const parser::ProcPointerInit
&);
963 void Post(const parser::ProcInterface
&);
964 void Post(const parser::ProcDecl
&);
965 bool Pre(const parser::TypeBoundProcedurePart
&);
966 void Post(const parser::TypeBoundProcedurePart
&);
967 void Post(const parser::ContainsStmt
&);
968 bool Pre(const parser::TypeBoundProcBinding
&) { return BeginAttrs(); }
969 void Post(const parser::TypeBoundProcBinding
&) { EndAttrs(); }
970 void Post(const parser::TypeBoundProcedureStmt::WithoutInterface
&);
971 void Post(const parser::TypeBoundProcedureStmt::WithInterface
&);
972 void Post(const parser::FinalProcedureStmt
&);
973 bool Pre(const parser::TypeBoundGenericStmt
&);
974 bool Pre(const parser::StructureDef
&); // returns false
975 bool Pre(const parser::Union::UnionStmt
&);
976 bool Pre(const parser::StructureField
&);
977 void Post(const parser::StructureField
&);
978 bool Pre(const parser::AllocateStmt
&);
979 void Post(const parser::AllocateStmt
&);
980 bool Pre(const parser::StructureConstructor
&);
981 bool Pre(const parser::NamelistStmt::Group
&);
982 bool Pre(const parser::IoControlSpec
&);
983 bool Pre(const parser::CommonStmt::Block
&);
984 bool Pre(const parser::CommonBlockObject
&);
985 void Post(const parser::CommonBlockObject
&);
986 bool Pre(const parser::EquivalenceStmt
&);
987 bool Pre(const parser::SaveStmt
&);
988 bool Pre(const parser::BasedPointerStmt
&);
990 void PointerInitialization(
991 const parser::Name
&, const parser::InitialDataTarget
&);
992 void PointerInitialization(
993 const parser::Name
&, const parser::ProcPointerInit
&);
994 void NonPointerInitialization(
995 const parser::Name
&, const parser::ConstantExpr
&);
996 void CheckExplicitInterface(const parser::Name
&);
997 void CheckBindings(const parser::TypeBoundProcedureStmt::WithoutInterface
&);
999 const parser::Name
*ResolveDesignator(const parser::Designator
&);
1004 Symbol
&DeclareObjectEntity(const parser::Name
&, Attrs
= Attrs
{});
1005 // Make sure that there's an entity in an enclosing scope called Name
1006 Symbol
&FindOrDeclareEnclosingEntity(const parser::Name
&);
1007 // Declare a LOCAL/LOCAL_INIT entity. If there isn't a type specified
1008 // it comes from the entity in the containing scope, or implicit rules.
1009 // Return pointer to the new symbol, or nullptr on error.
1010 Symbol
*DeclareLocalEntity(const parser::Name
&);
1011 // Declare a statement entity (i.e., an implied DO loop index for
1012 // a DATA statement or an array constructor). If there isn't an explict
1013 // type specified, implicit rules apply. Return pointer to the new symbol,
1014 // or nullptr on error.
1015 Symbol
*DeclareStatementEntity(const parser::DoVariable
&,
1016 const std::optional
<parser::IntegerTypeSpec
> &);
1017 Symbol
&MakeCommonBlockSymbol(const parser::Name
&);
1018 Symbol
&MakeCommonBlockSymbol(const std::optional
<parser::Name
> &);
1019 bool CheckUseError(const parser::Name
&);
1020 void CheckAccessibility(const SourceName
&, bool, Symbol
&);
1021 void CheckCommonBlocks();
1022 void CheckSaveStmts();
1023 void CheckEquivalenceSets();
1024 bool CheckNotInBlock(const char *);
1025 bool NameIsKnownOrIntrinsic(const parser::Name
&);
1026 void FinishNamelists();
1028 // Each of these returns a pointer to a resolved Name (i.e. with symbol)
1029 // or nullptr in case of error.
1030 const parser::Name
*ResolveStructureComponent(
1031 const parser::StructureComponent
&);
1032 const parser::Name
*ResolveDataRef(const parser::DataRef
&);
1033 const parser::Name
*ResolveName(const parser::Name
&);
1034 bool PassesSharedLocalityChecks(const parser::Name
&name
, Symbol
&symbol
);
1035 Symbol
*NoteInterfaceName(const parser::Name
&);
1036 bool IsUplevelReference(const Symbol
&);
1038 std::optional
<SourceName
> BeginCheckOnIndexUseInOwnBounds(
1039 const parser::DoVariable
&name
) {
1040 std::optional
<SourceName
> result
{checkIndexUseInOwnBounds_
};
1041 checkIndexUseInOwnBounds_
= name
.thing
.thing
.source
;
1044 void EndCheckOnIndexUseInOwnBounds(const std::optional
<SourceName
> &restore
) {
1045 checkIndexUseInOwnBounds_
= restore
;
1049 // The attribute corresponding to the statement containing an ObjectDecl
1050 std::optional
<Attr
> objectDeclAttr_
;
1051 // Info about current character type while walking DeclTypeSpec.
1052 // Also captures any "*length" specifier on an individual declaration.
1054 std::optional
<ParamValue
> length
;
1055 std::optional
<KindExpr
> kind
;
1057 // Info about current derived type or STRUCTURE while walking
1058 // DerivedTypeDef / StructureDef
1060 const parser::Name
*extends
{nullptr}; // EXTENDS(name)
1061 bool privateComps
{false}; // components are private by default
1062 bool privateBindings
{false}; // bindings are private by default
1063 bool sawContains
{false}; // currently processing bindings
1064 bool sequence
{false}; // is a sequence type
1065 const Symbol
*type
{nullptr}; // derived type being defined
1066 bool isStructure
{false}; // is a DEC STRUCTURE
1068 // In a ProcedureDeclarationStmt or ProcComponentDefStmt, this is
1069 // the interface name, if any.
1070 const parser::Name
*interfaceName_
{nullptr};
1071 // Map type-bound generic to binding names of its specific bindings
1072 std::multimap
<Symbol
*, const parser::Name
*> genericBindings_
;
1073 // Info about current ENUM
1074 struct EnumeratorState
{
1075 // Enum value must hold inside a C_INT (7.6.2).
1076 std::optional
<int> value
{0};
1077 } enumerationState_
;
1078 // Set for OldParameterStmt processing
1079 bool inOldStyleParameterStmt_
{false};
1080 // Set when walking DATA & array constructor implied DO loop bounds
1081 // to warn about use of the implied DO intex therein.
1082 std::optional
<SourceName
> checkIndexUseInOwnBounds_
;
1083 bool hasBindCName_
{false};
1085 bool HandleAttributeStmt(Attr
, const std::list
<parser::Name
> &);
1086 Symbol
&HandleAttributeStmt(Attr
, const parser::Name
&);
1087 Symbol
&DeclareUnknownEntity(const parser::Name
&, Attrs
);
1088 Symbol
&DeclareProcEntity(
1089 const parser::Name
&, Attrs
, const Symbol
*interface
);
1090 void SetType(const parser::Name
&, const DeclTypeSpec
&);
1091 std::optional
<DerivedTypeSpec
> ResolveDerivedType(const parser::Name
&);
1092 std::optional
<DerivedTypeSpec
> ResolveExtendsType(
1093 const parser::Name
&, const parser::Name
*);
1094 Symbol
*MakeTypeSymbol(const SourceName
&, Details
&&);
1095 Symbol
*MakeTypeSymbol(const parser::Name
&, Details
&&);
1096 bool OkToAddComponent(const parser::Name
&, const Symbol
* = nullptr);
1097 ParamValue
GetParamValue(
1098 const parser::TypeParamValue
&, common::TypeParamAttr attr
);
1099 void CheckCommonBlockDerivedType(const SourceName
&, const Symbol
&);
1100 std::optional
<MessageFixedText
> CheckSaveAttr(const Symbol
&);
1101 Attrs
HandleSaveName(const SourceName
&, Attrs
);
1102 void AddSaveName(std::set
<SourceName
> &, const SourceName
&);
1103 void SetSaveAttr(Symbol
&);
1104 bool HandleUnrestrictedSpecificIntrinsicFunction(const parser::Name
&);
1105 const parser::Name
*FindComponent(const parser::Name
*, const parser::Name
&);
1106 void Initialization(const parser::Name
&, const parser::Initialization
&,
1107 bool inComponentDecl
);
1108 bool PassesLocalityChecks(const parser::Name
&name
, Symbol
&symbol
);
1109 bool CheckForHostAssociatedImplicit(const parser::Name
&);
1111 // Declare an object or procedure entity.
1112 // T is one of: EntityDetails, ObjectEntityDetails, ProcEntityDetails
1113 template <typename T
>
1114 Symbol
&DeclareEntity(const parser::Name
&name
, Attrs attrs
) {
1115 Symbol
&symbol
{MakeSymbol(name
, attrs
)};
1116 if (context().HasError(symbol
) || symbol
.has
<T
>()) {
1117 return symbol
; // OK or error already reported
1118 } else if (symbol
.has
<UnknownDetails
>()) {
1119 symbol
.set_details(T
{});
1121 } else if (auto *details
{symbol
.detailsIf
<EntityDetails
>()}) {
1122 symbol
.set_details(T
{std::move(*details
)});
1124 } else if (std::is_same_v
<EntityDetails
, T
> &&
1125 (symbol
.has
<ObjectEntityDetails
>() ||
1126 symbol
.has
<ProcEntityDetails
>())) {
1127 return symbol
; // OK
1128 } else if (auto *details
{symbol
.detailsIf
<UseDetails
>()}) {
1130 "'%s' is use-associated from module '%s' and cannot be re-declared"_err_en_US
,
1131 name
.source
, GetUsedModule(*details
).name());
1132 } else if (auto *details
{symbol
.detailsIf
<SubprogramNameDetails
>()}) {
1133 if (details
->kind() == SubprogramKind::Module
) {
1135 "Declaration of '%s' conflicts with its use as module procedure"_err_en_US
,
1136 symbol
, "Module procedure definition"_en_US
);
1137 } else if (details
->kind() == SubprogramKind::Internal
) {
1139 "Declaration of '%s' conflicts with its use as internal procedure"_err_en_US
,
1140 symbol
, "Internal procedure definition"_en_US
);
1142 DIE("unexpected kind");
1144 } else if (std::is_same_v
<ObjectEntityDetails
, T
> &&
1145 symbol
.has
<ProcEntityDetails
>()) {
1147 name
, symbol
, "'%s' is already declared as a procedure"_err_en_US
);
1148 } else if (std::is_same_v
<ProcEntityDetails
, T
> &&
1149 symbol
.has
<ObjectEntityDetails
>()) {
1150 if (FindCommonBlockContaining(symbol
)) {
1151 SayWithDecl(name
, symbol
,
1152 "'%s' may not be a procedure as it is in a COMMON block"_err_en_US
);
1155 name
, symbol
, "'%s' is already declared as an object"_err_en_US
);
1157 } else if (!CheckPossibleBadForwardRef(symbol
)) {
1158 SayAlreadyDeclared(name
, symbol
);
1160 context().SetError(symbol
);
1163 bool HasCycle(const Symbol
&, const Symbol
*interface
);
1166 // Resolve construct entities and statement entities.
1167 // Check that construct names don't conflict with other names.
1168 class ConstructVisitor
: public virtual DeclarationVisitor
{
1170 bool Pre(const parser::ConcurrentHeader
&);
1171 bool Pre(const parser::LocalitySpec::Local
&);
1172 bool Pre(const parser::LocalitySpec::LocalInit
&);
1173 bool Pre(const parser::LocalitySpec::Shared
&);
1174 bool Pre(const parser::AcSpec
&);
1175 bool Pre(const parser::AcImpliedDo
&);
1176 bool Pre(const parser::DataImpliedDo
&);
1177 bool Pre(const parser::DataIDoObject
&);
1178 bool Pre(const parser::DataStmtObject
&);
1179 bool Pre(const parser::DataStmtValue
&);
1180 bool Pre(const parser::DoConstruct
&);
1181 void Post(const parser::DoConstruct
&);
1182 bool Pre(const parser::ForallConstruct
&);
1183 void Post(const parser::ForallConstruct
&);
1184 bool Pre(const parser::ForallStmt
&);
1185 void Post(const parser::ForallStmt
&);
1186 bool Pre(const parser::BlockStmt
&);
1187 bool Pre(const parser::EndBlockStmt
&);
1188 void Post(const parser::Selector
&);
1189 void Post(const parser::AssociateStmt
&);
1190 void Post(const parser::EndAssociateStmt
&);
1191 bool Pre(const parser::Association
&);
1192 void Post(const parser::SelectTypeStmt
&);
1193 void Post(const parser::SelectRankStmt
&);
1194 bool Pre(const parser::SelectTypeConstruct
&);
1195 void Post(const parser::SelectTypeConstruct
&);
1196 bool Pre(const parser::SelectTypeConstruct::TypeCase
&);
1197 void Post(const parser::SelectTypeConstruct::TypeCase
&);
1198 // Creates Block scopes with neither symbol name nor symbol details.
1199 bool Pre(const parser::SelectRankConstruct::RankCase
&);
1200 void Post(const parser::SelectRankConstruct::RankCase
&);
1201 bool Pre(const parser::TypeGuardStmt::Guard
&);
1202 void Post(const parser::TypeGuardStmt::Guard
&);
1203 void Post(const parser::SelectRankCaseStmt::Rank
&);
1204 bool Pre(const parser::ChangeTeamStmt
&);
1205 void Post(const parser::EndChangeTeamStmt
&);
1206 void Post(const parser::CoarrayAssociation
&);
1208 // Definitions of construct names
1209 bool Pre(const parser::WhereConstructStmt
&x
) { return CheckDef(x
.t
); }
1210 bool Pre(const parser::ForallConstructStmt
&x
) { return CheckDef(x
.t
); }
1211 bool Pre(const parser::CriticalStmt
&x
) { return CheckDef(x
.t
); }
1212 bool Pre(const parser::LabelDoStmt
&) {
1213 return false; // error recovery
1215 bool Pre(const parser::NonLabelDoStmt
&x
) { return CheckDef(x
.t
); }
1216 bool Pre(const parser::IfThenStmt
&x
) { return CheckDef(x
.t
); }
1217 bool Pre(const parser::SelectCaseStmt
&x
) { return CheckDef(x
.t
); }
1218 bool Pre(const parser::SelectRankConstruct
&);
1219 void Post(const parser::SelectRankConstruct
&);
1220 bool Pre(const parser::SelectRankStmt
&x
) {
1221 return CheckDef(std::get
<0>(x
.t
));
1223 bool Pre(const parser::SelectTypeStmt
&x
) {
1224 return CheckDef(std::get
<0>(x
.t
));
1227 // References to construct names
1228 void Post(const parser::MaskedElsewhereStmt
&x
) { CheckRef(x
.t
); }
1229 void Post(const parser::ElsewhereStmt
&x
) { CheckRef(x
.v
); }
1230 void Post(const parser::EndWhereStmt
&x
) { CheckRef(x
.v
); }
1231 void Post(const parser::EndForallStmt
&x
) { CheckRef(x
.v
); }
1232 void Post(const parser::EndCriticalStmt
&x
) { CheckRef(x
.v
); }
1233 void Post(const parser::EndDoStmt
&x
) { CheckRef(x
.v
); }
1234 void Post(const parser::ElseIfStmt
&x
) { CheckRef(x
.t
); }
1235 void Post(const parser::ElseStmt
&x
) { CheckRef(x
.v
); }
1236 void Post(const parser::EndIfStmt
&x
) { CheckRef(x
.v
); }
1237 void Post(const parser::CaseStmt
&x
) { CheckRef(x
.t
); }
1238 void Post(const parser::EndSelectStmt
&x
) { CheckRef(x
.v
); }
1239 void Post(const parser::SelectRankCaseStmt
&x
) { CheckRef(x
.t
); }
1240 void Post(const parser::TypeGuardStmt
&x
) { CheckRef(x
.t
); }
1241 void Post(const parser::CycleStmt
&x
) { CheckRef(x
.v
); }
1242 void Post(const parser::ExitStmt
&x
) { CheckRef(x
.v
); }
1245 // R1105 selector -> expr | variable
1246 // expr is set in either case unless there were errors
1249 Selector(const SourceName
&source
, MaybeExpr
&&expr
)
1250 : source
{source
}, expr
{std::move(expr
)} {}
1251 operator bool() const { return expr
.has_value(); }
1252 parser::CharBlock source
;
1255 // association -> [associate-name =>] selector
1256 struct Association
{
1257 const parser::Name
*name
{nullptr};
1260 std::vector
<Association
> associationStack_
;
1261 Association
*currentAssociation_
{nullptr};
1263 template <typename T
> bool CheckDef(const T
&t
) {
1264 return CheckDef(std::get
<std::optional
<parser::Name
>>(t
));
1266 template <typename T
> void CheckRef(const T
&t
) {
1267 CheckRef(std::get
<std::optional
<parser::Name
>>(t
));
1269 bool CheckDef(const std::optional
<parser::Name
> &);
1270 void CheckRef(const std::optional
<parser::Name
> &);
1271 const DeclTypeSpec
&ToDeclTypeSpec(evaluate::DynamicType
&&);
1272 const DeclTypeSpec
&ToDeclTypeSpec(
1273 evaluate::DynamicType
&&, MaybeSubscriptIntExpr
&&length
);
1274 Symbol
*MakeAssocEntity();
1275 void SetTypeFromAssociation(Symbol
&);
1276 void SetAttrsFromAssociation(Symbol
&);
1277 Selector
ResolveSelector(const parser::Selector
&);
1278 void ResolveIndexName(const parser::ConcurrentControl
&control
);
1279 void SetCurrentAssociation(std::size_t n
);
1280 Association
&GetCurrentAssociation();
1281 void PushAssociation();
1282 void PopAssociation(std::size_t count
= 1);
1285 // Create scopes for OpenACC constructs
1286 class AccVisitor
: public virtual DeclarationVisitor
{
1288 void AddAccSourceRange(const parser::CharBlock
&);
1290 static bool NeedsScope(const parser::OpenACCBlockConstruct
&);
1292 bool Pre(const parser::OpenACCBlockConstruct
&);
1293 void Post(const parser::OpenACCBlockConstruct
&);
1294 bool Pre(const parser::AccBeginBlockDirective
&x
) {
1295 AddAccSourceRange(x
.source
);
1298 void Post(const parser::AccBeginBlockDirective
&) {
1299 messageHandler().set_currStmtSource(std::nullopt
);
1301 bool Pre(const parser::AccEndBlockDirective
&x
) {
1302 AddAccSourceRange(x
.source
);
1305 void Post(const parser::AccEndBlockDirective
&) {
1306 messageHandler().set_currStmtSource(std::nullopt
);
1308 bool Pre(const parser::AccBeginLoopDirective
&x
) {
1309 AddAccSourceRange(x
.source
);
1312 void Post(const parser::AccBeginLoopDirective
&x
) {
1313 messageHandler().set_currStmtSource(std::nullopt
);
1317 bool AccVisitor::NeedsScope(const parser::OpenACCBlockConstruct
&x
) {
1318 const auto &beginBlockDir
{std::get
<parser::AccBeginBlockDirective
>(x
.t
)};
1319 const auto &beginDir
{std::get
<parser::AccBlockDirective
>(beginBlockDir
.t
)};
1320 switch (beginDir
.v
) {
1321 case llvm::acc::Directive::ACCD_data
:
1322 case llvm::acc::Directive::ACCD_host_data
:
1323 case llvm::acc::Directive::ACCD_kernels
:
1324 case llvm::acc::Directive::ACCD_parallel
:
1325 case llvm::acc::Directive::ACCD_serial
:
1332 void AccVisitor::AddAccSourceRange(const parser::CharBlock
&source
) {
1333 messageHandler().set_currStmtSource(source
);
1334 currScope().AddSourceRange(source
);
1337 bool AccVisitor::Pre(const parser::OpenACCBlockConstruct
&x
) {
1338 if (NeedsScope(x
)) {
1339 PushScope(Scope::Kind::OtherConstruct
, nullptr);
1344 void AccVisitor::Post(const parser::OpenACCBlockConstruct
&x
) {
1345 if (NeedsScope(x
)) {
1350 // Create scopes for OpenMP constructs
1351 class OmpVisitor
: public virtual DeclarationVisitor
{
1353 void AddOmpSourceRange(const parser::CharBlock
&);
1355 static bool NeedsScope(const parser::OpenMPBlockConstruct
&);
1357 bool Pre(const parser::OpenMPBlockConstruct
&);
1358 void Post(const parser::OpenMPBlockConstruct
&);
1359 bool Pre(const parser::OmpBeginBlockDirective
&x
) {
1360 AddOmpSourceRange(x
.source
);
1363 void Post(const parser::OmpBeginBlockDirective
&) {
1364 messageHandler().set_currStmtSource(std::nullopt
);
1366 bool Pre(const parser::OmpEndBlockDirective
&x
) {
1367 AddOmpSourceRange(x
.source
);
1370 void Post(const parser::OmpEndBlockDirective
&) {
1371 messageHandler().set_currStmtSource(std::nullopt
);
1374 bool Pre(const parser::OpenMPLoopConstruct
&) {
1375 PushScope(Scope::Kind::OtherConstruct
, nullptr);
1378 void Post(const parser::OpenMPLoopConstruct
&) { PopScope(); }
1379 bool Pre(const parser::OmpBeginLoopDirective
&x
) {
1380 AddOmpSourceRange(x
.source
);
1383 void Post(const parser::OmpBeginLoopDirective
&) {
1384 messageHandler().set_currStmtSource(std::nullopt
);
1386 bool Pre(const parser::OmpEndLoopDirective
&x
) {
1387 AddOmpSourceRange(x
.source
);
1390 void Post(const parser::OmpEndLoopDirective
&) {
1391 messageHandler().set_currStmtSource(std::nullopt
);
1394 bool Pre(const parser::OpenMPSectionsConstruct
&) {
1395 PushScope(Scope::Kind::OtherConstruct
, nullptr);
1398 void Post(const parser::OpenMPSectionsConstruct
&) { PopScope(); }
1399 bool Pre(const parser::OmpBeginSectionsDirective
&x
) {
1400 AddOmpSourceRange(x
.source
);
1403 void Post(const parser::OmpBeginSectionsDirective
&) {
1404 messageHandler().set_currStmtSource(std::nullopt
);
1406 bool Pre(const parser::OmpEndSectionsDirective
&x
) {
1407 AddOmpSourceRange(x
.source
);
1410 void Post(const parser::OmpEndSectionsDirective
&) {
1411 messageHandler().set_currStmtSource(std::nullopt
);
1415 bool OmpVisitor::NeedsScope(const parser::OpenMPBlockConstruct
&x
) {
1416 const auto &beginBlockDir
{std::get
<parser::OmpBeginBlockDirective
>(x
.t
)};
1417 const auto &beginDir
{std::get
<parser::OmpBlockDirective
>(beginBlockDir
.t
)};
1418 switch (beginDir
.v
) {
1419 case llvm::omp::Directive::OMPD_target_data
:
1420 case llvm::omp::Directive::OMPD_master
:
1421 case llvm::omp::Directive::OMPD_ordered
:
1422 case llvm::omp::Directive::OMPD_taskgroup
:
1429 void OmpVisitor::AddOmpSourceRange(const parser::CharBlock
&source
) {
1430 messageHandler().set_currStmtSource(source
);
1431 currScope().AddSourceRange(source
);
1434 bool OmpVisitor::Pre(const parser::OpenMPBlockConstruct
&x
) {
1435 if (NeedsScope(x
)) {
1436 PushScope(Scope::Kind::OtherConstruct
, nullptr);
1441 void OmpVisitor::Post(const parser::OpenMPBlockConstruct
&x
) {
1442 if (NeedsScope(x
)) {
1447 // Walk the parse tree and resolve names to symbols.
1448 class ResolveNamesVisitor
: public virtual ScopeHandler
,
1449 public ModuleVisitor
,
1450 public SubprogramVisitor
,
1451 public ConstructVisitor
,
1455 using AccVisitor::Post
;
1456 using AccVisitor::Pre
;
1457 using ArraySpecVisitor::Post
;
1458 using ConstructVisitor::Post
;
1459 using ConstructVisitor::Pre
;
1460 using DeclarationVisitor::Post
;
1461 using DeclarationVisitor::Pre
;
1462 using ImplicitRulesVisitor::Post
;
1463 using ImplicitRulesVisitor::Pre
;
1464 using InterfaceVisitor::Post
;
1465 using InterfaceVisitor::Pre
;
1466 using ModuleVisitor::Post
;
1467 using ModuleVisitor::Pre
;
1468 using OmpVisitor::Post
;
1469 using OmpVisitor::Pre
;
1470 using ScopeHandler::Post
;
1471 using ScopeHandler::Pre
;
1472 using SubprogramVisitor::Post
;
1473 using SubprogramVisitor::Pre
;
1475 ResolveNamesVisitor(
1476 SemanticsContext
&context
, ImplicitRulesMap
&rules
, Scope
&top
)
1477 : BaseVisitor
{context
, *this, rules
}, topScope_
{top
} {
1481 Scope
&topScope() const { return topScope_
; }
1483 // Default action for a parse tree node is to visit children.
1484 template <typename T
> bool Pre(const T
&) { return true; }
1485 template <typename T
> void Post(const T
&) {}
1487 bool Pre(const parser::SpecificationPart
&);
1488 bool Pre(const parser::Program
&);
1489 void Post(const parser::Program
&);
1490 bool Pre(const parser::ImplicitStmt
&);
1491 void Post(const parser::PointerObject
&);
1492 void Post(const parser::AllocateObject
&);
1493 bool Pre(const parser::PointerAssignmentStmt
&);
1494 void Post(const parser::Designator
&);
1495 void Post(const parser::SubstringInquiry
&);
1496 template <typename A
, typename B
>
1497 void Post(const parser::LoopBounds
<A
, B
> &x
) {
1498 ResolveName(*parser::Unwrap
<parser::Name
>(x
.name
));
1500 void Post(const parser::ProcComponentRef
&);
1501 bool Pre(const parser::FunctionReference
&);
1502 bool Pre(const parser::CallStmt
&);
1503 bool Pre(const parser::ImportStmt
&);
1504 void Post(const parser::TypeGuardStmt
&);
1505 bool Pre(const parser::StmtFunctionStmt
&);
1506 bool Pre(const parser::DefinedOpName
&);
1507 bool Pre(const parser::ProgramUnit
&);
1508 void Post(const parser::AssignStmt
&);
1509 void Post(const parser::AssignedGotoStmt
&);
1511 // These nodes should never be reached: they are handled in ProgramUnit
1512 bool Pre(const parser::MainProgram
&) {
1513 llvm_unreachable("This node is handled in ProgramUnit");
1515 bool Pre(const parser::FunctionSubprogram
&) {
1516 llvm_unreachable("This node is handled in ProgramUnit");
1518 bool Pre(const parser::SubroutineSubprogram
&) {
1519 llvm_unreachable("This node is handled in ProgramUnit");
1521 bool Pre(const parser::SeparateModuleSubprogram
&) {
1522 llvm_unreachable("This node is handled in ProgramUnit");
1524 bool Pre(const parser::Module
&) {
1525 llvm_unreachable("This node is handled in ProgramUnit");
1527 bool Pre(const parser::Submodule
&) {
1528 llvm_unreachable("This node is handled in ProgramUnit");
1530 bool Pre(const parser::BlockData
&) {
1531 llvm_unreachable("This node is handled in ProgramUnit");
1534 void NoteExecutablePartCall(Symbol::Flag
, const parser::Call
&);
1536 friend void ResolveSpecificationParts(SemanticsContext
&, const Symbol
&);
1539 // Kind of procedure we are expecting to see in a ProcedureDesignator
1540 std::optional
<Symbol::Flag
> expectedProcFlag_
;
1541 std::optional
<SourceName
> prevImportStmt_
;
1544 void PreSpecificationConstruct(const parser::SpecificationConstruct
&);
1545 void CreateCommonBlockSymbols(const parser::CommonStmt
&);
1546 void CreateGeneric(const parser::GenericSpec
&);
1547 void FinishSpecificationPart(const std::list
<parser::DeclarationConstruct
> &);
1548 void AnalyzeStmtFunctionStmt(const parser::StmtFunctionStmt
&);
1549 void CheckImports();
1550 void CheckImport(const SourceName
&, const SourceName
&);
1551 void HandleCall(Symbol::Flag
, const parser::Call
&);
1552 void HandleProcedureName(Symbol::Flag
, const parser::Name
&);
1553 bool CheckImplicitNoneExternal(const SourceName
&, const Symbol
&);
1554 bool SetProcFlag(const parser::Name
&, Symbol
&, Symbol::Flag
);
1555 void ResolveSpecificationParts(ProgramTree
&);
1556 void AddSubpNames(ProgramTree
&);
1557 bool BeginScopeForNode(const ProgramTree
&);
1558 void EndScopeForNode(const ProgramTree
&);
1559 void FinishSpecificationParts(const ProgramTree
&);
1560 void FinishDerivedTypeInstantiation(Scope
&);
1561 void ResolveExecutionParts(const ProgramTree
&);
1564 // ImplicitRules implementation
1566 bool ImplicitRules::isImplicitNoneType() const {
1567 if (isImplicitNoneType_
) {
1569 } else if (map_
.empty() && inheritFromParent_
) {
1570 return parent_
->isImplicitNoneType();
1572 return false; // default if not specified
1576 bool ImplicitRules::isImplicitNoneExternal() const {
1577 if (isImplicitNoneExternal_
) {
1579 } else if (inheritFromParent_
) {
1580 return parent_
->isImplicitNoneExternal();
1582 return false; // default if not specified
1586 const DeclTypeSpec
*ImplicitRules::GetType(
1587 SourceName name
, bool respectImplicitNoneType
) const {
1588 char ch
{name
.begin()[0]};
1589 if (isImplicitNoneType_
&& respectImplicitNoneType
) {
1591 } else if (auto it
{map_
.find(ch
)}; it
!= map_
.end()) {
1592 return &*it
->second
;
1593 } else if (inheritFromParent_
) {
1594 return parent_
->GetType(name
, respectImplicitNoneType
);
1595 } else if (ch
>= 'i' && ch
<= 'n') {
1596 return &context_
.MakeNumericType(TypeCategory::Integer
);
1597 } else if (ch
>= 'a' && ch
<= 'z') {
1598 return &context_
.MakeNumericType(TypeCategory::Real
);
1604 void ImplicitRules::SetTypeMapping(const DeclTypeSpec
&type
,
1605 parser::Location fromLetter
, parser::Location toLetter
) {
1606 for (char ch
= *fromLetter
; ch
; ch
= ImplicitRules::Incr(ch
)) {
1607 auto res
{map_
.emplace(ch
, type
)};
1609 context_
.Say(parser::CharBlock
{fromLetter
},
1610 "More than one implicit type specified for '%c'"_err_en_US
, ch
);
1612 if (ch
== *toLetter
) {
1618 // Return the next char after ch in a way that works for ASCII or EBCDIC.
1619 // Return '\0' for the char after 'z'.
1620 char ImplicitRules::Incr(char ch
) {
1633 llvm::raw_ostream
&operator<<(
1634 llvm::raw_ostream
&o
, const ImplicitRules
&implicitRules
) {
1635 o
<< "ImplicitRules:\n";
1636 for (char ch
= 'a'; ch
; ch
= ImplicitRules::Incr(ch
)) {
1637 ShowImplicitRule(o
, implicitRules
, ch
);
1639 ShowImplicitRule(o
, implicitRules
, '_');
1640 ShowImplicitRule(o
, implicitRules
, '$');
1641 ShowImplicitRule(o
, implicitRules
, '@');
1644 void ShowImplicitRule(
1645 llvm::raw_ostream
&o
, const ImplicitRules
&implicitRules
, char ch
) {
1646 auto it
{implicitRules
.map_
.find(ch
)};
1647 if (it
!= implicitRules
.map_
.end()) {
1648 o
<< " " << ch
<< ": " << *it
->second
<< '\n';
1652 template <typename T
> void BaseVisitor::Walk(const T
&x
) {
1653 parser::Walk(x
, *this_
);
1656 void BaseVisitor::MakePlaceholder(
1657 const parser::Name
&name
, MiscDetails::Kind kind
) {
1659 name
.symbol
= &context_
->globalScope().MakeSymbol(
1660 name
.source
, Attrs
{}, MiscDetails
{kind
});
1664 // AttrsVisitor implementation
1666 bool AttrsVisitor::BeginAttrs() {
1668 attrs_
= std::make_optional
<Attrs
>();
1671 Attrs
AttrsVisitor::GetAttrs() {
1675 Attrs
AttrsVisitor::EndAttrs() {
1676 Attrs result
{GetAttrs()};
1678 passName_
= std::nullopt
;
1683 bool AttrsVisitor::SetPassNameOn(Symbol
&symbol
) {
1687 common::visit(common::visitors
{
1688 [&](ProcEntityDetails
&x
) { x
.set_passName(*passName_
); },
1689 [&](ProcBindingDetails
&x
) { x
.set_passName(*passName_
); },
1690 [](auto &) { common::die("unexpected pass name"); },
1696 void AttrsVisitor::SetBindNameOn(Symbol
&symbol
) {
1697 if (!attrs_
|| !attrs_
->test(Attr::BIND_C
)) {
1700 std::optional
<std::string
> label
{
1701 evaluate::GetScalarConstantValue
<evaluate::Ascii
>(bindName_
)};
1702 // 18.9.2(2): discard leading and trailing blanks
1704 symbol
.SetIsExplicitBindName(true);
1705 auto first
{label
->find_first_not_of(" ")};
1706 if (first
== std::string::npos
) {
1707 // Empty NAME= means no binding at all (18.10.2p2)
1710 auto last
{label
->find_last_not_of(" ")};
1711 label
= label
->substr(first
, last
- first
+ 1);
1713 label
= symbol
.name().ToString();
1715 // Check if a symbol has two Bind names.
1716 std::string oldBindName
;
1717 if (symbol
.GetBindName()) {
1718 oldBindName
= *symbol
.GetBindName();
1720 symbol
.SetBindName(std::move(*label
));
1721 if (!oldBindName
.empty()) {
1722 if (const std::string
* newBindName
{symbol
.GetBindName()}) {
1723 if (oldBindName
!= *newBindName
) {
1724 Say(symbol
.name(), "The entity '%s' has multiple BIND names"_err_en_US
);
1730 void AttrsVisitor::Post(const parser::LanguageBindingSpec
&x
) {
1732 if (CheckAndSet(Attr::BIND_C
)) {
1734 bindName_
= EvaluateExpr(*x
.v
);
1738 bool AttrsVisitor::Pre(const parser::IntentSpec
&x
) {
1740 CheckAndSet(IntentSpecToAttr(x
));
1743 bool AttrsVisitor::Pre(const parser::Pass
&x
) {
1744 if (CheckAndSet(Attr::PASS
)) {
1746 passName_
= x
.v
->source
;
1747 MakePlaceholder(*x
.v
, MiscDetails::Kind::PassName
);
1753 // C730, C743, C755, C778, C1543 say no attribute or prefix repetitions
1754 bool AttrsVisitor::IsDuplicateAttr(Attr attrName
) {
1755 if (attrs_
->test(attrName
)) {
1756 Say(currStmtSource().value(),
1757 "Attribute '%s' cannot be used more than once"_warn_en_US
,
1758 AttrToString(attrName
));
1764 // See if attrName violates a constraint cause by a conflict. attr1 and attr2
1765 // name attributes that cannot be used on the same declaration
1766 bool AttrsVisitor::HaveAttrConflict(Attr attrName
, Attr attr1
, Attr attr2
) {
1767 if ((attrName
== attr1
&& attrs_
->test(attr2
)) ||
1768 (attrName
== attr2
&& attrs_
->test(attr1
))) {
1769 Say(currStmtSource().value(),
1770 "Attributes '%s' and '%s' conflict with each other"_err_en_US
,
1771 AttrToString(attr1
), AttrToString(attr2
));
1777 bool AttrsVisitor::IsConflictingAttr(Attr attrName
) {
1778 return HaveAttrConflict(attrName
, Attr::INTENT_IN
, Attr::INTENT_INOUT
) ||
1779 HaveAttrConflict(attrName
, Attr::INTENT_IN
, Attr::INTENT_OUT
) ||
1780 HaveAttrConflict(attrName
, Attr::INTENT_INOUT
, Attr::INTENT_OUT
) ||
1781 HaveAttrConflict(attrName
, Attr::PASS
, Attr::NOPASS
) || // C781
1782 HaveAttrConflict(attrName
, Attr::PURE
, Attr::IMPURE
) ||
1783 HaveAttrConflict(attrName
, Attr::PUBLIC
, Attr::PRIVATE
) ||
1784 HaveAttrConflict(attrName
, Attr::RECURSIVE
, Attr::NON_RECURSIVE
);
1786 bool AttrsVisitor::CheckAndSet(Attr attrName
) {
1788 if (IsConflictingAttr(attrName
) || IsDuplicateAttr(attrName
)) {
1791 attrs_
->set(attrName
);
1795 // DeclTypeSpecVisitor implementation
1797 const DeclTypeSpec
*DeclTypeSpecVisitor::GetDeclTypeSpec() {
1798 return state_
.declTypeSpec
;
1801 void DeclTypeSpecVisitor::BeginDeclTypeSpec() {
1802 CHECK(!state_
.expectDeclTypeSpec
);
1803 CHECK(!state_
.declTypeSpec
);
1804 state_
.expectDeclTypeSpec
= true;
1806 void DeclTypeSpecVisitor::EndDeclTypeSpec() {
1807 CHECK(state_
.expectDeclTypeSpec
);
1811 void DeclTypeSpecVisitor::SetDeclTypeSpecCategory(
1812 DeclTypeSpec::Category category
) {
1813 CHECK(state_
.expectDeclTypeSpec
);
1814 state_
.derived
.category
= category
;
1817 bool DeclTypeSpecVisitor::Pre(const parser::TypeGuardStmt
&) {
1818 BeginDeclTypeSpec();
1821 void DeclTypeSpecVisitor::Post(const parser::TypeGuardStmt
&) {
1825 void DeclTypeSpecVisitor::Post(const parser::TypeSpec
&typeSpec
) {
1826 // Record the resolved DeclTypeSpec in the parse tree for use by
1827 // expression semantics if the DeclTypeSpec is a valid TypeSpec.
1828 // The grammar ensures that it's an intrinsic or derived type spec,
1829 // not TYPE(*) or CLASS(*) or CLASS(T).
1830 if (const DeclTypeSpec
* spec
{state_
.declTypeSpec
}) {
1831 switch (spec
->category()) {
1832 case DeclTypeSpec::Numeric
:
1833 case DeclTypeSpec::Logical
:
1834 case DeclTypeSpec::Character
:
1835 typeSpec
.declTypeSpec
= spec
;
1837 case DeclTypeSpec::TypeDerived
:
1838 if (const DerivedTypeSpec
* derived
{spec
->AsDerived()}) {
1839 CheckForAbstractType(derived
->typeSymbol()); // C703
1840 typeSpec
.declTypeSpec
= spec
;
1849 void DeclTypeSpecVisitor::Post(
1850 const parser::IntrinsicTypeSpec::DoublePrecision
&) {
1851 MakeNumericType(TypeCategory::Real
, context().doublePrecisionKind());
1853 void DeclTypeSpecVisitor::Post(
1854 const parser::IntrinsicTypeSpec::DoubleComplex
&) {
1855 MakeNumericType(TypeCategory::Complex
, context().doublePrecisionKind());
1857 void DeclTypeSpecVisitor::MakeNumericType(TypeCategory category
, int kind
) {
1858 SetDeclTypeSpec(context().MakeNumericType(category
, kind
));
1861 void DeclTypeSpecVisitor::CheckForAbstractType(const Symbol
&typeSymbol
) {
1862 if (typeSymbol
.attrs().test(Attr::ABSTRACT
)) {
1863 Say("ABSTRACT derived type may not be used here"_err_en_US
);
1867 void DeclTypeSpecVisitor::Post(const parser::DeclarationTypeSpec::ClassStar
&) {
1868 SetDeclTypeSpec(context().globalScope().MakeClassStarType());
1870 void DeclTypeSpecVisitor::Post(const parser::DeclarationTypeSpec::TypeStar
&) {
1871 SetDeclTypeSpec(context().globalScope().MakeTypeStarType());
1874 // Check that we're expecting to see a DeclTypeSpec (and haven't seen one yet)
1875 // and save it in state_.declTypeSpec.
1876 void DeclTypeSpecVisitor::SetDeclTypeSpec(const DeclTypeSpec
&declTypeSpec
) {
1877 CHECK(state_
.expectDeclTypeSpec
);
1878 CHECK(!state_
.declTypeSpec
);
1879 state_
.declTypeSpec
= &declTypeSpec
;
1882 KindExpr
DeclTypeSpecVisitor::GetKindParamExpr(
1883 TypeCategory category
, const std::optional
<parser::KindSelector
> &kind
) {
1884 return AnalyzeKindSelector(context(), category
, kind
);
1887 // MessageHandler implementation
1889 Message
&MessageHandler::Say(MessageFixedText
&&msg
) {
1890 return context_
->Say(currStmtSource().value(), std::move(msg
));
1892 Message
&MessageHandler::Say(MessageFormattedText
&&msg
) {
1893 return context_
->Say(currStmtSource().value(), std::move(msg
));
1895 Message
&MessageHandler::Say(const SourceName
&name
, MessageFixedText
&&msg
) {
1896 return Say(name
, std::move(msg
), name
);
1899 // ImplicitRulesVisitor implementation
1901 void ImplicitRulesVisitor::Post(const parser::ParameterStmt
&) {
1902 prevParameterStmt_
= currStmtSource();
1905 bool ImplicitRulesVisitor::Pre(const parser::ImplicitStmt
&x
) {
1907 common::visit(common::visitors
{
1908 [&](const std::list
<ImplicitNoneNameSpec
> &y
) {
1909 return HandleImplicitNone(y
);
1911 [&](const std::list
<parser::ImplicitSpec
> &) {
1912 if (prevImplicitNoneType_
) {
1913 Say("IMPLICIT statement after IMPLICIT NONE or "
1914 "IMPLICIT NONE(TYPE) statement"_err_en_US
);
1917 implicitRules_
->set_isImplicitNoneType(false);
1922 prevImplicit_
= currStmtSource();
1926 bool ImplicitRulesVisitor::Pre(const parser::LetterSpec
&x
) {
1927 auto loLoc
{std::get
<parser::Location
>(x
.t
)};
1929 if (auto hiLocOpt
{std::get
<std::optional
<parser::Location
>>(x
.t
)}) {
1931 if (*hiLoc
< *loLoc
) {
1932 Say(hiLoc
, "'%s' does not follow '%s' alphabetically"_err_en_US
,
1933 std::string(hiLoc
, 1), std::string(loLoc
, 1));
1937 implicitRules_
->SetTypeMapping(*GetDeclTypeSpec(), loLoc
, hiLoc
);
1941 bool ImplicitRulesVisitor::Pre(const parser::ImplicitSpec
&) {
1942 BeginDeclTypeSpec();
1943 set_allowForwardReferenceToDerivedType(true);
1947 void ImplicitRulesVisitor::Post(const parser::ImplicitSpec
&) {
1951 void ImplicitRulesVisitor::SetScope(const Scope
&scope
) {
1952 implicitRules_
= &DEREF(implicitRulesMap_
).at(&scope
);
1953 prevImplicit_
= std::nullopt
;
1954 prevImplicitNone_
= std::nullopt
;
1955 prevImplicitNoneType_
= std::nullopt
;
1956 prevParameterStmt_
= std::nullopt
;
1958 void ImplicitRulesVisitor::BeginScope(const Scope
&scope
) {
1959 // find or create implicit rules for this scope
1960 DEREF(implicitRulesMap_
).try_emplace(&scope
, context(), implicitRules_
);
1964 // TODO: for all of these errors, reference previous statement too
1965 bool ImplicitRulesVisitor::HandleImplicitNone(
1966 const std::list
<ImplicitNoneNameSpec
> &nameSpecs
) {
1967 if (prevImplicitNone_
) {
1968 Say("More than one IMPLICIT NONE statement"_err_en_US
);
1969 Say(*prevImplicitNone_
, "Previous IMPLICIT NONE statement"_en_US
);
1972 if (prevParameterStmt_
) {
1973 Say("IMPLICIT NONE statement after PARAMETER statement"_err_en_US
);
1976 prevImplicitNone_
= currStmtSource();
1977 bool implicitNoneTypeNever
{
1978 context().IsEnabled(common::LanguageFeature::ImplicitNoneTypeNever
)};
1979 if (nameSpecs
.empty()) {
1980 if (!implicitNoneTypeNever
) {
1981 prevImplicitNoneType_
= currStmtSource();
1982 implicitRules_
->set_isImplicitNoneType(true);
1983 if (prevImplicit_
) {
1984 Say("IMPLICIT NONE statement after IMPLICIT statement"_err_en_US
);
1991 for (const auto noneSpec
: nameSpecs
) {
1993 case ImplicitNoneNameSpec::External
:
1994 implicitRules_
->set_isImplicitNoneExternal(true);
1997 case ImplicitNoneNameSpec::Type
:
1998 if (!implicitNoneTypeNever
) {
1999 prevImplicitNoneType_
= currStmtSource();
2000 implicitRules_
->set_isImplicitNoneType(true);
2001 if (prevImplicit_
) {
2002 Say("IMPLICIT NONE(TYPE) after IMPLICIT statement"_err_en_US
);
2011 Say("TYPE specified more than once in IMPLICIT NONE statement"_err_en_US
);
2014 if (sawExternal
> 1) {
2015 Say("EXTERNAL specified more than once in IMPLICIT NONE statement"_err_en_US
);
2022 // ArraySpecVisitor implementation
2024 void ArraySpecVisitor::Post(const parser::ArraySpec
&x
) {
2025 CHECK(arraySpec_
.empty());
2026 arraySpec_
= AnalyzeArraySpec(context(), x
);
2028 void ArraySpecVisitor::Post(const parser::ComponentArraySpec
&x
) {
2029 CHECK(arraySpec_
.empty());
2030 arraySpec_
= AnalyzeArraySpec(context(), x
);
2032 void ArraySpecVisitor::Post(const parser::CoarraySpec
&x
) {
2033 CHECK(coarraySpec_
.empty());
2034 coarraySpec_
= AnalyzeCoarraySpec(context(), x
);
2037 const ArraySpec
&ArraySpecVisitor::arraySpec() {
2038 return !arraySpec_
.empty() ? arraySpec_
: attrArraySpec_
;
2040 const ArraySpec
&ArraySpecVisitor::coarraySpec() {
2041 return !coarraySpec_
.empty() ? coarraySpec_
: attrCoarraySpec_
;
2043 void ArraySpecVisitor::BeginArraySpec() {
2044 CHECK(arraySpec_
.empty());
2045 CHECK(coarraySpec_
.empty());
2046 CHECK(attrArraySpec_
.empty());
2047 CHECK(attrCoarraySpec_
.empty());
2049 void ArraySpecVisitor::EndArraySpec() {
2050 CHECK(arraySpec_
.empty());
2051 CHECK(coarraySpec_
.empty());
2052 attrArraySpec_
.clear();
2053 attrCoarraySpec_
.clear();
2055 void ArraySpecVisitor::PostAttrSpec() {
2056 // Save dimension/codimension from attrs so we can process array/coarray-spec
2057 // on the entity-decl
2058 if (!arraySpec_
.empty()) {
2059 if (attrArraySpec_
.empty()) {
2060 attrArraySpec_
= arraySpec_
;
2063 Say(currStmtSource().value(),
2064 "Attribute 'DIMENSION' cannot be used more than once"_err_en_US
);
2067 if (!coarraySpec_
.empty()) {
2068 if (attrCoarraySpec_
.empty()) {
2069 attrCoarraySpec_
= coarraySpec_
;
2070 coarraySpec_
.clear();
2072 Say(currStmtSource().value(),
2073 "Attribute 'CODIMENSION' cannot be used more than once"_err_en_US
);
2078 // FuncResultStack implementation
2080 FuncResultStack::~FuncResultStack() { CHECK(stack_
.empty()); }
2082 void FuncResultStack::CompleteFunctionResultType() {
2083 // If the function has a type in the prefix, process it now.
2084 FuncInfo
*info
{Top()};
2085 if (info
&& &info
->scope
== &scopeHandler_
.currScope()) {
2086 if (info
->parsedType
&& info
->resultSymbol
) {
2087 scopeHandler_
.messageHandler().set_currStmtSource(info
->source
);
2088 if (const auto *type
{
2089 scopeHandler_
.ProcessTypeSpec(*info
->parsedType
, true)}) {
2090 Symbol
&symbol
{*info
->resultSymbol
};
2091 if (!scopeHandler_
.context().HasError(symbol
)) {
2092 if (symbol
.GetType()) {
2093 scopeHandler_
.Say(symbol
.name(),
2094 "Function cannot have both an explicit type prefix and a RESULT suffix"_err_en_US
);
2095 scopeHandler_
.context().SetError(symbol
);
2097 symbol
.SetType(*type
);
2101 info
->parsedType
= nullptr;
2106 // Called from ConvertTo{Object/Proc}Entity to cope with any appearance
2107 // of the function result in a specification expression.
2108 void FuncResultStack::CompleteTypeIfFunctionResult(Symbol
&symbol
) {
2109 if (FuncInfo
* info
{Top()}) {
2110 if (info
->resultSymbol
== &symbol
) {
2111 CompleteFunctionResultType();
2116 void FuncResultStack::Pop() {
2117 if (!stack_
.empty() && &stack_
.back().scope
== &scopeHandler_
.currScope()) {
2122 // ScopeHandler implementation
2124 void ScopeHandler::SayAlreadyDeclared(const parser::Name
&name
, Symbol
&prev
) {
2125 SayAlreadyDeclared(name
.source
, prev
);
2127 void ScopeHandler::SayAlreadyDeclared(const SourceName
&name
, Symbol
&prev
) {
2128 if (context().HasError(prev
)) {
2129 // don't report another error about prev
2131 if (const auto *details
{prev
.detailsIf
<UseDetails
>()}) {
2132 Say(name
, "'%s' is already declared in this scoping unit"_err_en_US
)
2133 .Attach(details
->location(),
2134 "It is use-associated with '%s' in module '%s'"_en_US
,
2135 details
->symbol().name(), GetUsedModule(*details
).name());
2137 SayAlreadyDeclared(name
, prev
.name());
2139 context().SetError(prev
);
2142 void ScopeHandler::SayAlreadyDeclared(
2143 const SourceName
&name1
, const SourceName
&name2
) {
2144 if (name1
.begin() < name2
.begin()) {
2145 SayAlreadyDeclared(name2
, name1
);
2147 Say(name1
, "'%s' is already declared in this scoping unit"_err_en_US
)
2148 .Attach(name2
, "Previous declaration of '%s'"_en_US
, name2
);
2152 void ScopeHandler::SayWithReason(const parser::Name
&name
, Symbol
&symbol
,
2153 MessageFixedText
&&msg1
, Message
&&msg2
) {
2154 bool isFatal
{msg1
.IsFatal()};
2155 Say(name
, std::move(msg1
), symbol
.name()).Attach(std::move(msg2
));
2156 context().SetError(symbol
, isFatal
);
2159 void ScopeHandler::SayWithDecl(
2160 const parser::Name
&name
, Symbol
&symbol
, MessageFixedText
&&msg
) {
2161 bool isFatal
{msg
.IsFatal()};
2162 Say(name
, std::move(msg
), symbol
.name())
2163 .Attach(Message
{name
.source
,
2164 symbol
.test(Symbol::Flag::Implicit
)
2165 ? "Implicit declaration of '%s'"_en_US
2166 : "Declaration of '%s'"_en_US
,
2168 context().SetError(symbol
, isFatal
);
2171 void ScopeHandler::SayLocalMustBeVariable(
2172 const parser::Name
&name
, Symbol
&symbol
) {
2173 SayWithDecl(name
, symbol
,
2174 "The name '%s' must be a variable to appear"
2175 " in a locality-spec"_err_en_US
);
2178 void ScopeHandler::SayDerivedType(
2179 const SourceName
&name
, MessageFixedText
&&msg
, const Scope
&type
) {
2180 const Symbol
&typeSymbol
{DEREF(type
.GetSymbol())};
2181 Say(name
, std::move(msg
), name
, typeSymbol
.name())
2182 .Attach(typeSymbol
.name(), "Declaration of derived type '%s'"_en_US
,
2185 void ScopeHandler::Say2(const SourceName
&name1
, MessageFixedText
&&msg1
,
2186 const SourceName
&name2
, MessageFixedText
&&msg2
) {
2187 Say(name1
, std::move(msg1
)).Attach(name2
, std::move(msg2
), name2
);
2189 void ScopeHandler::Say2(const SourceName
&name
, MessageFixedText
&&msg1
,
2190 Symbol
&symbol
, MessageFixedText
&&msg2
) {
2191 bool isFatal
{msg1
.IsFatal()};
2192 Say2(name
, std::move(msg1
), symbol
.name(), std::move(msg2
));
2193 context().SetError(symbol
, isFatal
);
2195 void ScopeHandler::Say2(const parser::Name
&name
, MessageFixedText
&&msg1
,
2196 Symbol
&symbol
, MessageFixedText
&&msg2
) {
2197 bool isFatal
{msg1
.IsFatal()};
2198 Say2(name
.source
, std::move(msg1
), symbol
.name(), std::move(msg2
));
2199 context().SetError(symbol
, isFatal
);
2202 // This is essentially GetProgramUnitContaining(), but it can return
2203 // a mutable Scope &, it ignores statement functions, and it fails
2204 // gracefully for error recovery (returning the original Scope).
2205 template <typename T
> static T
&GetInclusiveScope(T
&scope
) {
2206 for (T
*s
{&scope
}; !s
->IsGlobal(); s
= &s
->parent()) {
2207 switch (s
->kind()) {
2208 case Scope::Kind::Module
:
2209 case Scope::Kind::MainProgram
:
2210 case Scope::Kind::Subprogram
:
2211 case Scope::Kind::BlockData
:
2212 if (!s
->IsStmtFunction()) {
2222 Scope
&ScopeHandler::InclusiveScope() { return GetInclusiveScope(currScope()); }
2224 Scope
*ScopeHandler::GetHostProcedure() {
2225 Scope
&parent
{InclusiveScope().parent()};
2226 switch (parent
.kind()) {
2227 case Scope::Kind::Subprogram
:
2229 case Scope::Kind::MainProgram
:
2236 Scope
&ScopeHandler::NonDerivedTypeScope() {
2237 return currScope_
->IsDerivedType() ? currScope_
->parent() : *currScope_
;
2240 void ScopeHandler::PushScope(Scope::Kind kind
, Symbol
*symbol
) {
2241 PushScope(currScope().MakeScope(kind
, symbol
));
2243 void ScopeHandler::PushScope(Scope
&scope
) {
2244 currScope_
= &scope
;
2245 auto kind
{currScope_
->kind()};
2246 if (kind
!= Scope::Kind::BlockConstruct
&&
2247 kind
!= Scope::Kind::OtherConstruct
) {
2250 // The name of a module or submodule cannot be "used" in its scope,
2251 // as we read 19.3.1(2), so we allow the name to be used as a local
2252 // identifier in the module or submodule too. Same with programs
2253 // (14.1(3)) and BLOCK DATA.
2254 if (!currScope_
->IsDerivedType() && kind
!= Scope::Kind::Module
&&
2255 kind
!= Scope::Kind::MainProgram
&& kind
!= Scope::Kind::BlockData
) {
2256 if (auto *symbol
{scope
.symbol()}) {
2257 // Create a dummy symbol so we can't create another one with the same
2258 // name. It might already be there if we previously pushed the scope.
2259 SourceName name
{symbol
->name()};
2260 if (!FindInScope(scope
, name
)) {
2261 auto &newSymbol
{MakeSymbol(name
)};
2262 if (kind
== Scope::Kind::Subprogram
) {
2263 // Allow for recursive references. If this symbol is a function
2264 // without an explicit RESULT(), this new symbol will be discarded
2265 // and replaced with an object of the same name.
2266 newSymbol
.set_details(HostAssocDetails
{*symbol
});
2268 newSymbol
.set_details(MiscDetails
{MiscDetails::Kind::ScopeName
});
2274 void ScopeHandler::PopScope() {
2275 // Entities that are not yet classified as objects or procedures are now
2276 // assumed to be objects.
2277 // TODO: Statement functions
2278 for (auto &pair
: currScope()) {
2279 ConvertToObjectEntity(*pair
.second
);
2281 funcResultStack_
.Pop();
2282 // If popping back into a global scope, pop back to the main global scope.
2283 SetScope(currScope_
->parent().IsGlobal() ? context().globalScope()
2284 : currScope_
->parent());
2286 void ScopeHandler::SetScope(Scope
&scope
) {
2287 currScope_
= &scope
;
2288 ImplicitRulesVisitor::SetScope(InclusiveScope());
2291 Symbol
*ScopeHandler::FindSymbol(const parser::Name
&name
) {
2292 return FindSymbol(currScope(), name
);
2294 Symbol
*ScopeHandler::FindSymbol(const Scope
&scope
, const parser::Name
&name
) {
2295 if (scope
.IsDerivedType()) {
2296 if (Symbol
* symbol
{scope
.FindComponent(name
.source
)}) {
2297 if (symbol
->has
<TypeParamDetails
>()) {
2298 return Resolve(name
, symbol
);
2301 return FindSymbol(scope
.parent(), name
);
2303 // In EQUIVALENCE statements only resolve names in the local scope, see
2304 // 19.5.1.4, paragraph 2, item (10)
2305 return Resolve(name
,
2306 inEquivalenceStmt_
? FindInScope(scope
, name
)
2307 : scope
.FindSymbol(name
.source
));
2311 Symbol
&ScopeHandler::MakeSymbol(
2312 Scope
&scope
, const SourceName
&name
, Attrs attrs
) {
2313 if (Symbol
* symbol
{FindInScope(scope
, name
)}) {
2314 CheckDuplicatedAttrs(name
, *symbol
, attrs
);
2315 SetExplicitAttrs(*symbol
, attrs
);
2318 const auto pair
{scope
.try_emplace(name
, attrs
, UnknownDetails
{})};
2319 CHECK(pair
.second
); // name was not found, so must be able to add
2320 return *pair
.first
->second
;
2323 Symbol
&ScopeHandler::MakeSymbol(const SourceName
&name
, Attrs attrs
) {
2324 return MakeSymbol(currScope(), name
, attrs
);
2326 Symbol
&ScopeHandler::MakeSymbol(const parser::Name
&name
, Attrs attrs
) {
2327 return Resolve(name
, MakeSymbol(name
.source
, attrs
));
2329 Symbol
&ScopeHandler::MakeHostAssocSymbol(
2330 const parser::Name
&name
, const Symbol
&hostSymbol
) {
2331 Symbol
&symbol
{*NonDerivedTypeScope()
2332 .try_emplace(name
.source
, HostAssocDetails
{hostSymbol
})
2334 name
.symbol
= &symbol
;
2335 symbol
.attrs() = hostSymbol
.attrs(); // TODO: except PRIVATE, PUBLIC?
2336 symbol
.flags() = hostSymbol
.flags();
2339 Symbol
&ScopeHandler::CopySymbol(const SourceName
&name
, const Symbol
&symbol
) {
2340 CHECK(!FindInScope(name
));
2341 return MakeSymbol(currScope(), name
, symbol
.attrs());
2344 // Look for name only in scope, not in enclosing scopes.
2345 Symbol
*ScopeHandler::FindInScope(
2346 const Scope
&scope
, const parser::Name
&name
) {
2347 return Resolve(name
, FindInScope(scope
, name
.source
));
2349 Symbol
*ScopeHandler::FindInScope(const Scope
&scope
, const SourceName
&name
) {
2350 // all variants of names, e.g. "operator(.ne.)" for "operator(/=)"
2351 for (const std::string
&n
: GetAllNames(context(), name
)) {
2352 auto it
{scope
.find(SourceName
{n
})};
2353 if (it
!= scope
.end()) {
2354 return &*it
->second
;
2360 // Find a component or type parameter by name in a derived type or its parents.
2361 Symbol
*ScopeHandler::FindInTypeOrParents(
2362 const Scope
&scope
, const parser::Name
&name
) {
2363 return Resolve(name
, scope
.FindComponent(name
.source
));
2365 Symbol
*ScopeHandler::FindInTypeOrParents(const parser::Name
&name
) {
2366 return FindInTypeOrParents(currScope(), name
);
2368 Symbol
*ScopeHandler::FindInScopeOrBlockConstructs(
2369 const Scope
&scope
, SourceName name
) {
2370 if (Symbol
* symbol
{FindInScope(scope
, name
)}) {
2373 for (const Scope
&child
: scope
.children()) {
2374 if (child
.kind() == Scope::Kind::BlockConstruct
) {
2375 if (Symbol
* symbol
{FindInScopeOrBlockConstructs(child
, name
)}) {
2383 void ScopeHandler::EraseSymbol(const parser::Name
&name
) {
2384 currScope().erase(name
.source
);
2385 name
.symbol
= nullptr;
2388 static bool NeedsType(const Symbol
&symbol
) {
2389 return !symbol
.GetType() &&
2390 common::visit(common::visitors
{
2391 [](const EntityDetails
&) { return true; },
2392 [](const ObjectEntityDetails
&) { return true; },
2393 [](const AssocEntityDetails
&) { return true; },
2394 [&](const ProcEntityDetails
&p
) {
2395 return symbol
.test(Symbol::Flag::Function
) &&
2396 !symbol
.attrs().test(Attr::INTRINSIC
) &&
2397 !p
.type() && !p
.procInterface();
2399 [](const auto &) { return false; },
2404 void ScopeHandler::ApplyImplicitRules(
2405 Symbol
&symbol
, bool allowForwardReference
) {
2406 funcResultStack_
.CompleteTypeIfFunctionResult(symbol
);
2407 if (context().HasError(symbol
) || !NeedsType(symbol
)) {
2410 if (const DeclTypeSpec
* type
{GetImplicitType(symbol
)}) {
2411 symbol
.set(Symbol::Flag::Implicit
);
2412 symbol
.SetType(*type
);
2415 if (symbol
.has
<ProcEntityDetails
>() && !symbol
.attrs().test(Attr::EXTERNAL
)) {
2416 std::optional
<Symbol::Flag
> functionOrSubroutineFlag
;
2417 if (symbol
.test(Symbol::Flag::Function
)) {
2418 functionOrSubroutineFlag
= Symbol::Flag::Function
;
2419 } else if (symbol
.test(Symbol::Flag::Subroutine
)) {
2420 functionOrSubroutineFlag
= Symbol::Flag::Subroutine
;
2422 if (IsIntrinsic(symbol
.name(), functionOrSubroutineFlag
)) {
2423 // type will be determined in expression semantics
2424 AcquireIntrinsicProcedureFlags(symbol
);
2428 if (allowForwardReference
&& ImplicitlyTypeForwardRef(symbol
)) {
2431 if (!context().HasError(symbol
)) {
2432 Say(symbol
.name(), "No explicit type declared for '%s'"_err_en_US
);
2433 context().SetError(symbol
);
2437 // Extension: Allow forward references to scalar integer dummy arguments
2438 // or variables in COMMON to appear in specification expressions under
2439 // IMPLICIT NONE(TYPE) when what would otherwise have been their implicit
2440 // type is default INTEGER.
2441 bool ScopeHandler::ImplicitlyTypeForwardRef(Symbol
&symbol
) {
2442 if (!inSpecificationPart_
|| context().HasError(symbol
) ||
2443 !(IsDummy(symbol
) || FindCommonBlockContaining(symbol
)) ||
2444 symbol
.Rank() != 0 ||
2445 !context().languageFeatures().IsEnabled(
2446 common::LanguageFeature::ForwardRefImplicitNone
)) {
2449 const DeclTypeSpec
*type
{
2450 GetImplicitType(symbol
, false /*ignore IMPLICIT NONE*/)};
2451 if (!type
|| !type
->IsNumeric(TypeCategory::Integer
)) {
2454 auto kind
{evaluate::ToInt64(type
->numericTypeSpec().kind())};
2455 if (!kind
|| *kind
!= context().GetDefaultKind(TypeCategory::Integer
)) {
2458 if (!ConvertToObjectEntity(symbol
)) {
2461 // TODO: check no INTENT(OUT) if dummy?
2462 if (context().languageFeatures().ShouldWarn(
2463 common::LanguageFeature::ForwardRefImplicitNone
)) {
2465 "'%s' was used without (or before) being explicitly typed"_warn_en_US
,
2468 symbol
.set(Symbol::Flag::Implicit
);
2469 symbol
.SetType(*type
);
2473 // Ensure that the symbol for an intrinsic procedure is marked with
2474 // the INTRINSIC attribute. Also set PURE &/or ELEMENTAL as
2476 void ScopeHandler::AcquireIntrinsicProcedureFlags(Symbol
&symbol
) {
2477 SetImplicitAttr(symbol
, Attr::INTRINSIC
);
2478 switch (context().intrinsics().GetIntrinsicClass(symbol
.name().ToString())) {
2479 case evaluate::IntrinsicClass::elementalFunction
:
2480 case evaluate::IntrinsicClass::elementalSubroutine
:
2481 SetExplicitAttr(symbol
, Attr::ELEMENTAL
);
2482 SetExplicitAttr(symbol
, Attr::PURE
);
2484 case evaluate::IntrinsicClass::impureSubroutine
:
2487 SetExplicitAttr(symbol
, Attr::PURE
);
2491 const DeclTypeSpec
*ScopeHandler::GetImplicitType(
2492 Symbol
&symbol
, bool respectImplicitNoneType
) {
2493 const Scope
*scope
{&symbol
.owner()};
2494 if (scope
->IsGlobal()) {
2495 scope
= &currScope();
2497 scope
= &GetInclusiveScope(*scope
);
2498 const auto *type
{implicitRulesMap_
->at(scope
).GetType(
2499 symbol
.name(), respectImplicitNoneType
)};
2501 if (const DerivedTypeSpec
* derived
{type
->AsDerived()}) {
2502 // Resolve any forward-referenced derived type; a quick no-op else.
2503 auto &instantiatable
{*const_cast<DerivedTypeSpec
*>(derived
)};
2504 instantiatable
.Instantiate(currScope());
2510 void ScopeHandler::CheckEntryDummyUse(SourceName source
, Symbol
*symbol
) {
2511 if (!inSpecificationPart_
&& symbol
&&
2512 symbol
->test(Symbol::Flag::EntryDummyArgument
)) {
2514 "Dummy argument '%s' may not be used before its ENTRY statement"_err_en_US
,
2516 symbol
->set(Symbol::Flag::EntryDummyArgument
, false);
2520 // Convert symbol to be a ObjectEntity or return false if it can't be.
2521 bool ScopeHandler::ConvertToObjectEntity(Symbol
&symbol
) {
2522 if (symbol
.has
<ObjectEntityDetails
>()) {
2524 } else if (symbol
.has
<UnknownDetails
>()) {
2525 // These are attributes that a name could have picked up from
2526 // an attribute statement or type declaration statement.
2527 if (symbol
.attrs().HasAny({Attr::EXTERNAL
, Attr::INTRINSIC
})) {
2530 symbol
.set_details(ObjectEntityDetails
{});
2531 } else if (auto *details
{symbol
.detailsIf
<EntityDetails
>()}) {
2532 if (symbol
.attrs().HasAny({Attr::EXTERNAL
, Attr::INTRINSIC
})) {
2535 funcResultStack_
.CompleteTypeIfFunctionResult(symbol
);
2536 symbol
.set_details(ObjectEntityDetails
{std::move(*details
)});
2537 } else if (auto *useDetails
{symbol
.detailsIf
<UseDetails
>()}) {
2538 return useDetails
->symbol().has
<ObjectEntityDetails
>();
2539 } else if (auto *hostDetails
{symbol
.detailsIf
<HostAssocDetails
>()}) {
2540 return hostDetails
->symbol().has
<ObjectEntityDetails
>();
2546 // Convert symbol to be a ProcEntity or return false if it can't be.
2547 bool ScopeHandler::ConvertToProcEntity(Symbol
&symbol
) {
2548 if (symbol
.has
<ProcEntityDetails
>()) {
2550 } else if (symbol
.has
<UnknownDetails
>()) {
2551 symbol
.set_details(ProcEntityDetails
{});
2552 } else if (auto *details
{symbol
.detailsIf
<EntityDetails
>()}) {
2553 if (IsFunctionResult(symbol
) &&
2554 !(IsPointer(symbol
) && symbol
.attrs().test(Attr::EXTERNAL
))) {
2555 // Don't turn function result into a procedure pointer unless both
2556 // POINTER and EXTERNAL
2559 funcResultStack_
.CompleteTypeIfFunctionResult(symbol
);
2560 symbol
.set_details(ProcEntityDetails
{std::move(*details
)});
2561 if (symbol
.GetType() && !symbol
.test(Symbol::Flag::Implicit
)) {
2562 CHECK(!symbol
.test(Symbol::Flag::Subroutine
));
2563 symbol
.set(Symbol::Flag::Function
);
2565 } else if (auto *useDetails
{symbol
.detailsIf
<UseDetails
>()}) {
2566 return useDetails
->symbol().has
<ProcEntityDetails
>();
2567 } else if (auto *hostDetails
{symbol
.detailsIf
<HostAssocDetails
>()}) {
2568 return hostDetails
->symbol().has
<ProcEntityDetails
>();
2575 const DeclTypeSpec
&ScopeHandler::MakeNumericType(
2576 TypeCategory category
, const std::optional
<parser::KindSelector
> &kind
) {
2577 KindExpr value
{GetKindParamExpr(category
, kind
)};
2578 if (auto known
{evaluate::ToInt64(value
)}) {
2579 return MakeNumericType(category
, static_cast<int>(*known
));
2581 return currScope_
->MakeNumericType(category
, std::move(value
));
2585 const DeclTypeSpec
&ScopeHandler::MakeNumericType(
2586 TypeCategory category
, int kind
) {
2587 return context().MakeNumericType(category
, kind
);
2590 const DeclTypeSpec
&ScopeHandler::MakeLogicalType(
2591 const std::optional
<parser::KindSelector
> &kind
) {
2592 KindExpr value
{GetKindParamExpr(TypeCategory::Logical
, kind
)};
2593 if (auto known
{evaluate::ToInt64(value
)}) {
2594 return MakeLogicalType(static_cast<int>(*known
));
2596 return currScope_
->MakeLogicalType(std::move(value
));
2600 const DeclTypeSpec
&ScopeHandler::MakeLogicalType(int kind
) {
2601 return context().MakeLogicalType(kind
);
2604 void ScopeHandler::NotePossibleBadForwardRef(const parser::Name
&name
) {
2605 if (inSpecificationPart_
&& name
.symbol
) {
2606 auto kind
{currScope().kind()};
2607 if ((kind
== Scope::Kind::Subprogram
&& !currScope().IsStmtFunction()) ||
2608 kind
== Scope::Kind::BlockConstruct
) {
2609 bool isHostAssociated
{&name
.symbol
->owner() == &currScope()
2610 ? name
.symbol
->has
<HostAssocDetails
>()
2611 : name
.symbol
->owner().Contains(currScope())};
2612 if (isHostAssociated
) {
2613 specPartState_
.forwardRefs
.insert(name
.source
);
2619 std::optional
<SourceName
> ScopeHandler::HadForwardRef(
2620 const Symbol
&symbol
) const {
2621 auto iter
{specPartState_
.forwardRefs
.find(symbol
.name())};
2622 if (iter
!= specPartState_
.forwardRefs
.end()) {
2625 return std::nullopt
;
2628 bool ScopeHandler::CheckPossibleBadForwardRef(const Symbol
&symbol
) {
2629 if (!context().HasError(symbol
)) {
2630 if (auto fwdRef
{HadForwardRef(symbol
)}) {
2631 const Symbol
*outer
{symbol
.owner().FindSymbol(symbol
.name())};
2632 if (outer
&& symbol
.has
<UseDetails
>() &&
2633 &symbol
.GetUltimate() == &outer
->GetUltimate()) {
2634 // e.g. IMPORT of host's USE association
2638 "Forward reference to '%s' is not allowed in the same specification part"_err_en_US
,
2640 .Attach(symbol
.name(), "Later declaration of '%s'"_en_US
, *fwdRef
);
2641 context().SetError(symbol
);
2644 if ((IsDummy(symbol
) || FindCommonBlockContaining(symbol
)) &&
2645 isImplicitNoneType() && symbol
.test(Symbol::Flag::Implicit
) &&
2646 !context().HasError(symbol
)) {
2647 // Dummy or COMMON was implicitly typed despite IMPLICIT NONE(TYPE) in
2648 // ApplyImplicitRules() due to use in a specification expression,
2649 // and no explicit type declaration appeared later.
2650 Say(symbol
.name(), "No explicit type declared for '%s'"_err_en_US
);
2651 context().SetError(symbol
);
2658 void ScopeHandler::MakeExternal(Symbol
&symbol
) {
2659 if (!symbol
.attrs().test(Attr::EXTERNAL
)) {
2660 SetImplicitAttr(symbol
, Attr::EXTERNAL
);
2661 if (symbol
.attrs().test(Attr::INTRINSIC
)) { // C840
2663 "Symbol '%s' cannot have both EXTERNAL and INTRINSIC attributes"_err_en_US
,
2669 bool ScopeHandler::CheckDuplicatedAttr(
2670 SourceName name
, const Symbol
&symbol
, Attr attr
) {
2671 if (attr
== Attr::SAVE
) {
2672 // checked elsewhere
2673 } else if (symbol
.attrs().test(attr
)) { // C815
2674 if (symbol
.implicitAttrs().test(attr
)) {
2675 // Implied attribute is now confirmed explicitly
2677 Say(name
, "%s attribute was already specified on '%s'"_err_en_US
,
2678 EnumToString(attr
), name
);
2685 bool ScopeHandler::CheckDuplicatedAttrs(
2686 SourceName name
, const Symbol
&symbol
, Attrs attrs
) {
2688 attrs
.IterateOverMembers(
2689 [&](Attr x
) { ok
&= CheckDuplicatedAttr(name
, symbol
, x
); });
2693 // ModuleVisitor implementation
2695 bool ModuleVisitor::Pre(const parser::Only
&x
) {
2696 common::visit(common::visitors
{
2697 [&](const Indirection
<parser::GenericSpec
> &generic
) {
2698 GenericSpecInfo genericSpecInfo
{generic
.value()};
2699 AddUseOnly(genericSpecInfo
.symbolName());
2700 AddUse(genericSpecInfo
);
2702 [&](const parser::Name
&name
) {
2703 AddUseOnly(name
.source
);
2704 Resolve(name
, AddUse(name
.source
, name
.source
).use
);
2706 [&](const parser::Rename
&rename
) { Walk(rename
); },
2712 bool ModuleVisitor::Pre(const parser::Rename::Names
&x
) {
2713 const auto &localName
{std::get
<0>(x
.t
)};
2714 const auto &useName
{std::get
<1>(x
.t
)};
2715 AddUseRename(useName
.source
);
2716 SymbolRename rename
{AddUse(localName
.source
, useName
.source
)};
2717 if (rename
.use
&& localName
.source
!= useName
.source
) {
2718 EraseRenamedSymbol(*rename
.use
);
2720 Resolve(useName
, rename
.use
);
2721 Resolve(localName
, rename
.local
);
2724 bool ModuleVisitor::Pre(const parser::Rename::Operators
&x
) {
2725 const parser::DefinedOpName
&local
{std::get
<0>(x
.t
)};
2726 const parser::DefinedOpName
&use
{std::get
<1>(x
.t
)};
2727 GenericSpecInfo localInfo
{local
};
2728 GenericSpecInfo useInfo
{use
};
2729 if (IsIntrinsicOperator(context(), local
.v
.source
)) {
2731 "Intrinsic operator '%s' may not be used as a defined operator"_err_en_US
);
2732 } else if (IsLogicalConstant(context(), local
.v
.source
)) {
2734 "Logical constant '%s' may not be used as a defined operator"_err_en_US
);
2736 SymbolRename rename
{AddUse(localInfo
.symbolName(), useInfo
.symbolName())};
2738 EraseRenamedSymbol(*rename
.use
);
2740 useInfo
.Resolve(rename
.use
);
2741 localInfo
.Resolve(rename
.local
);
2746 // Set useModuleScope_ to the Scope of the module being used.
2747 bool ModuleVisitor::Pre(const parser::UseStmt
&x
) {
2748 std::optional
<bool> isIntrinsic
;
2750 isIntrinsic
= *x
.nature
== parser::UseStmt::ModuleNature::Intrinsic
;
2751 AddAndCheckExplicitIntrinsicUse(x
.moduleName
.source
, *isIntrinsic
);
2752 } else if (currScope().IsModule() && currScope().symbol() &&
2753 currScope().symbol()->attrs().test(Attr::INTRINSIC
)) {
2754 // Intrinsic modules USE only other intrinsic modules
2757 useModuleScope_
= FindModule(x
.moduleName
, isIntrinsic
);
2758 if (!useModuleScope_
) {
2761 // use the name from this source file
2762 useModuleScope_
->symbol()->ReplaceName(x
.moduleName
.source
);
2766 void ModuleVisitor::Post(const parser::UseStmt
&x
) {
2767 if (const auto *list
{std::get_if
<std::list
<parser::Rename
>>(&x
.u
)}) {
2768 // Not a use-only: collect the names that were used in renames,
2769 // then add a use for each public name that was not renamed.
2770 std::set
<SourceName
> useNames
;
2771 for (const auto &rename
: *list
) {
2772 common::visit(common::visitors
{
2773 [&](const parser::Rename::Names
&names
) {
2774 useNames
.insert(std::get
<1>(names
.t
).source
);
2776 [&](const parser::Rename::Operators
&ops
) {
2777 useNames
.insert(std::get
<1>(ops
.t
).v
.source
);
2782 for (const auto &[name
, symbol
] : *useModuleScope_
) {
2783 if (symbol
->attrs().test(Attr::PUBLIC
) && !IsUseRenamed(symbol
->name()) &&
2784 (!symbol
->attrs().test(Attr::INTRINSIC
) ||
2785 symbol
->has
<UseDetails
>()) &&
2786 !symbol
->has
<MiscDetails
>() && useNames
.count(name
) == 0) {
2787 SourceName location
{x
.moduleName
.source
};
2788 if (auto *localSymbol
{FindInScope(name
)}) {
2789 DoAddUse(location
, localSymbol
->name(), *localSymbol
, *symbol
);
2791 DoAddUse(location
, location
, CopySymbol(name
, *symbol
), *symbol
);
2796 useModuleScope_
= nullptr;
2799 ModuleVisitor::SymbolRename
ModuleVisitor::AddUse(
2800 const SourceName
&localName
, const SourceName
&useName
) {
2801 return AddUse(localName
, useName
, FindInScope(*useModuleScope_
, useName
));
2804 ModuleVisitor::SymbolRename
ModuleVisitor::AddUse(
2805 const SourceName
&localName
, const SourceName
&useName
, Symbol
*useSymbol
) {
2806 if (!useModuleScope_
) {
2807 return {}; // error occurred finding module
2810 Say(useName
, "'%s' not found in module '%s'"_err_en_US
, MakeOpName(useName
),
2811 useModuleScope_
->GetName().value());
2814 if (useSymbol
->attrs().test(Attr::PRIVATE
) &&
2815 !FindModuleFileContaining(currScope())) {
2816 // Privacy is not enforced in module files so that generic interfaces
2817 // can be resolved to private specific procedures in specification
2819 Say(useName
, "'%s' is PRIVATE in '%s'"_err_en_US
, MakeOpName(useName
),
2820 useModuleScope_
->GetName().value());
2823 auto &localSymbol
{MakeSymbol(localName
)};
2824 DoAddUse(useName
, localName
, localSymbol
, *useSymbol
);
2825 return {&localSymbol
, useSymbol
};
2828 // symbol must be either a Use or a Generic formed by merging two uses.
2829 // Convert it to a UseError with this additional location.
2830 static bool ConvertToUseError(
2831 Symbol
&symbol
, const SourceName
&location
, const Scope
&module
) {
2832 const auto *useDetails
{symbol
.detailsIf
<UseDetails
>()};
2834 if (auto *genericDetails
{symbol
.detailsIf
<GenericDetails
>()}) {
2835 if (!genericDetails
->uses().empty()) {
2836 useDetails
= &genericDetails
->uses().at(0)->get
<UseDetails
>();
2842 UseErrorDetails
{*useDetails
}.add_occurrence(location
, module
));
2849 // If a symbol has previously been USE-associated and did not appear in a USE
2850 // ONLY clause, erase it from the current scope. This is needed when a name
2851 // appears in a USE rename clause.
2852 void ModuleVisitor::EraseRenamedSymbol(const Symbol
&useSymbol
) {
2853 const SourceName
&name
{useSymbol
.name()};
2854 if (const Symbol
* symbol
{FindInScope(name
)}) {
2855 if (auto *useDetails
{symbol
->detailsIf
<UseDetails
>()}) {
2856 const Symbol
&moduleSymbol
{useDetails
->symbol()};
2857 if (moduleSymbol
.name() == name
&&
2858 moduleSymbol
.owner() == useSymbol
.owner() && IsUseRenamed(name
) &&
2860 EraseSymbol(*symbol
);
2866 void ModuleVisitor::DoAddUse(SourceName location
, SourceName localName
,
2867 Symbol
&localSymbol
, const Symbol
&useSymbol
) {
2868 if (localName
!= useSymbol
.name()) {
2869 EraseRenamedSymbol(useSymbol
);
2871 if (auto *details
{localSymbol
.detailsIf
<UseErrorDetails
>()}) {
2872 details
->add_occurrence(location
, *useModuleScope_
);
2876 if (localSymbol
.has
<UnknownDetails
>()) {
2877 localSymbol
.set_details(UseDetails
{localName
, useSymbol
});
2878 localSymbol
.attrs() =
2879 useSymbol
.attrs() & ~Attrs
{Attr::PUBLIC
, Attr::PRIVATE
};
2880 localSymbol
.implicitAttrs() =
2881 localSymbol
.attrs() & Attrs
{Attr::ASYNCHRONOUS
, Attr::VOLATILE
};
2882 localSymbol
.flags() = useSymbol
.flags();
2886 Symbol
&localUltimate
{localSymbol
.GetUltimate()};
2887 const Symbol
&useUltimate
{useSymbol
.GetUltimate()};
2888 if (&localUltimate
== &useUltimate
) {
2889 // use-associating the same symbol again -- ok
2893 auto checkAmbiguousDerivedType
{[this, location
, localName
](
2894 const Symbol
*t1
, const Symbol
*t2
) {
2898 t1
= &t1
->GetUltimate();
2899 t2
= &t2
->GetUltimate();
2902 "Generic interface '%s' has ambiguous derived types from modules '%s' and '%s'"_err_en_US
,
2903 localName
, t1
->owner().GetName().value(),
2904 t2
->owner().GetName().value());
2910 auto *localGeneric
{localUltimate
.detailsIf
<GenericDetails
>()};
2911 const auto *useGeneric
{useUltimate
.detailsIf
<GenericDetails
>()};
2912 auto combine
{false};
2915 if (!checkAmbiguousDerivedType(
2916 localGeneric
->derivedType(), useGeneric
->derivedType())) {
2920 } else if (useUltimate
.has
<DerivedTypeDetails
>()) {
2921 if (checkAmbiguousDerivedType(
2922 &useUltimate
, localGeneric
->derivedType())) {
2927 } else if (&useUltimate
== &BypassGeneric(localUltimate
).GetUltimate()) {
2928 return; // nothing to do; used subprogram is local's specific
2930 } else if (useGeneric
) {
2931 if (localUltimate
.has
<DerivedTypeDetails
>()) {
2932 if (checkAmbiguousDerivedType(
2933 &localUltimate
, useGeneric
->derivedType())) {
2938 } else if (&localUltimate
== &BypassGeneric(useUltimate
).GetUltimate()) {
2939 // Local is the specific of the used generic; replace it.
2940 EraseSymbol(localSymbol
);
2941 Symbol
&newSymbol
{MakeSymbol(localName
,
2942 useUltimate
.attrs() & ~Attrs
{Attr::PUBLIC
, Attr::PRIVATE
},
2943 UseDetails
{localName
, useUltimate
})};
2944 newSymbol
.flags() = useSymbol
.flags();
2948 auto localClass
{ClassifyProcedure(localUltimate
)};
2949 auto useClass
{ClassifyProcedure(useUltimate
)};
2950 if (localClass
== useClass
&&
2951 (localClass
== ProcedureDefinitionClass::Intrinsic
||
2952 localClass
== ProcedureDefinitionClass::External
) &&
2953 localUltimate
.name() == useUltimate
.name()) {
2954 auto localChars
{evaluate::characteristics::Procedure::Characterize(
2955 localUltimate
, GetFoldingContext())};
2956 auto useChars
{evaluate::characteristics::Procedure::Characterize(
2957 useUltimate
, GetFoldingContext())};
2958 if (localChars
&& useChars
) {
2959 if (*localChars
== *useChars
) {
2960 // Same intrinsic or external procedure defined identically in two
2968 if (!ConvertToUseError(localSymbol
, location
, *useModuleScope_
)) {
2970 "Cannot use-associate '%s'; it is already declared in this scope"_err_en_US
,
2972 .Attach(localSymbol
.name(), "Previous declaration of '%s'"_en_US
,
2978 // Two items are being use-associated from different modules
2979 // to the same local name. At least one of them must be a generic,
2980 // and the other one can be a generic or a derived type.
2981 // (It could also have been the specific of the generic, but those
2982 // cases are handled above without needing to make a local copy of the
2986 if (localSymbol
.has
<UseDetails
>()) {
2987 // Create a local copy of a previously use-associated generic so that
2988 // it can be locally extended without corrupting the original.
2989 GenericDetails generic
;
2990 generic
.CopyFrom(*localGeneric
);
2991 if (localGeneric
->specific()) {
2992 generic
.set_specific(*localGeneric
->specific());
2994 EraseSymbol(localSymbol
);
2995 Symbol
&newSymbol
{MakeSymbol(
2996 localSymbol
.name(), localSymbol
.attrs(), std::move(generic
))};
2997 newSymbol
.flags() = localSymbol
.flags();
2998 localGeneric
= &newSymbol
.get
<GenericDetails
>();
2999 localGeneric
->AddUse(localSymbol
);
3002 // Combine two use-associated generics
3003 localSymbol
.attrs() =
3004 useSymbol
.attrs() & ~Attrs
{Attr::PUBLIC
, Attr::PRIVATE
};
3005 localSymbol
.flags() = useSymbol
.flags();
3006 AddGenericUse(*localGeneric
, localName
, useUltimate
);
3007 localGeneric
->CopyFrom(*useGeneric
);
3008 if (useGeneric
->specific()) {
3009 if (!localGeneric
->specific()) {
3010 localGeneric
->set_specific(
3011 *const_cast<Symbol
*>(useGeneric
->specific()));
3012 } else if (&localGeneric
->specific()->GetUltimate() !=
3013 &useGeneric
->specific()->GetUltimate()) {
3015 "Cannot use-associate generic interface '%s' with specific procedure of the same name when another such generic is in scope"_err_en_US
,
3018 localSymbol
.name(), "Previous USE of '%s'"_en_US
, localName
);
3022 CHECK(useUltimate
.has
<DerivedTypeDetails
>());
3023 localGeneric
->set_derivedType(
3024 AddGenericUse(*localGeneric
, localName
, useUltimate
));
3027 CHECK(useGeneric
&& localUltimate
.has
<DerivedTypeDetails
>());
3028 CHECK(localSymbol
.has
<UseDetails
>());
3029 // Create a local copy of the use-associated generic, then extend it
3030 // with the local derived type.
3031 GenericDetails generic
;
3032 generic
.CopyFrom(*useGeneric
);
3033 if (useGeneric
->specific()) {
3034 generic
.set_specific(*const_cast<Symbol
*>(useGeneric
->specific()));
3036 EraseSymbol(localSymbol
);
3037 Symbol
&newSymbol
{MakeSymbol(localName
,
3038 useUltimate
.attrs() & ~Attrs
{Attr::PUBLIC
, Attr::PRIVATE
},
3039 std::move(generic
))};
3040 newSymbol
.flags() = useUltimate
.flags();
3041 auto &newUseGeneric
{newSymbol
.get
<GenericDetails
>()};
3042 AddGenericUse(newUseGeneric
, localName
, useUltimate
);
3043 newUseGeneric
.AddUse(localSymbol
);
3044 newUseGeneric
.set_derivedType(localSymbol
);
3048 void ModuleVisitor::AddUse(const GenericSpecInfo
&info
) {
3049 if (useModuleScope_
) {
3050 const auto &name
{info
.symbolName()};
3051 auto rename
{AddUse(name
, name
, FindInScope(*useModuleScope_
, name
))};
3052 info
.Resolve(rename
.use
);
3056 // Create a UseDetails symbol for this USE and add it to generic
3057 Symbol
&ModuleVisitor::AddGenericUse(
3058 GenericDetails
&generic
, const SourceName
&name
, const Symbol
&useSymbol
) {
3060 currScope().MakeSymbol(name
, {}, UseDetails
{name
, useSymbol
})};
3061 generic
.AddUse(newSymbol
);
3066 void ModuleVisitor::AddAndCheckExplicitIntrinsicUse(
3067 SourceName name
, bool isIntrinsic
) {
3069 if (auto iter
{explicitNonIntrinsicUses_
.find(name
)};
3070 iter
!= explicitNonIntrinsicUses_
.end()) {
3072 "Cannot USE,INTRINSIC module '%s' in the same scope as USE,NON_INTRINSIC"_err_en_US
,
3074 .Attach(*iter
, "Previous USE of '%s'"_en_US
, *iter
);
3076 explicitIntrinsicUses_
.insert(name
);
3078 if (auto iter
{explicitIntrinsicUses_
.find(name
)};
3079 iter
!= explicitIntrinsicUses_
.end()) {
3081 "Cannot USE,NON_INTRINSIC module '%s' in the same scope as USE,INTRINSIC"_err_en_US
,
3083 .Attach(*iter
, "Previous USE of '%s'"_en_US
, *iter
);
3085 explicitNonIntrinsicUses_
.insert(name
);
3089 bool ModuleVisitor::BeginSubmodule(
3090 const parser::Name
&name
, const parser::ParentIdentifier
&parentId
) {
3091 const auto &ancestorName
{std::get
<parser::Name
>(parentId
.t
)};
3092 Scope
*parentScope
{nullptr};
3093 Scope
*ancestor
{FindModule(ancestorName
, false /*not intrinsic*/)};
3095 if (const auto &parentName
{
3096 std::get
<std::optional
<parser::Name
>>(parentId
.t
)}) {
3097 parentScope
= FindModule(*parentName
, false /*not intrinsic*/, ancestor
);
3099 parentScope
= ancestor
;
3103 PushScope(*parentScope
);
3105 // Error recovery: there's no ancestor scope, so create a dummy one to
3106 // hold the submodule's scope.
3107 SourceName dummyName
{context().GetTempName(currScope())};
3108 Symbol
&dummySymbol
{MakeSymbol(dummyName
, Attrs
{}, ModuleDetails
{false})};
3109 PushScope(Scope::Kind::Module
, &dummySymbol
);
3110 parentScope
= &currScope();
3112 BeginModule(name
, true);
3113 if (ancestor
&& !ancestor
->AddSubmodule(name
.source
, currScope())) {
3114 Say(name
, "Module '%s' already has a submodule named '%s'"_err_en_US
,
3115 ancestorName
.source
, name
.source
);
3120 void ModuleVisitor::BeginModule(const parser::Name
&name
, bool isSubmodule
) {
3121 auto &symbol
{MakeSymbol(name
, ModuleDetails
{isSubmodule
})};
3122 auto &details
{symbol
.get
<ModuleDetails
>()};
3123 PushScope(Scope::Kind::Module
, &symbol
);
3124 details
.set_scope(&currScope());
3125 defaultAccess_
= Attr::PUBLIC
;
3126 prevAccessStmt_
= std::nullopt
;
3129 // Find a module or submodule by name and return its scope.
3130 // If ancestor is present, look for a submodule of that ancestor module.
3131 // May have to read a .mod file to find it.
3132 // If an error occurs, report it and return nullptr.
3133 Scope
*ModuleVisitor::FindModule(const parser::Name
&name
,
3134 std::optional
<bool> isIntrinsic
, Scope
*ancestor
) {
3135 ModFileReader reader
{context()};
3136 Scope
*scope
{reader
.Read(name
.source
, isIntrinsic
, ancestor
)};
3140 if (DoesScopeContain(scope
, currScope())) { // 14.2.2(1)
3141 Say(name
, "Module '%s' cannot USE itself"_err_en_US
);
3143 Resolve(name
, scope
->symbol());
3147 void ModuleVisitor::ApplyDefaultAccess() {
3148 for (auto &pair
: currScope()) {
3149 Symbol
&symbol
= *pair
.second
;
3150 if (!symbol
.attrs().HasAny({Attr::PUBLIC
, Attr::PRIVATE
})) {
3151 SetImplicitAttr(symbol
, defaultAccess_
);
3156 // InterfaceVistor implementation
3158 bool InterfaceVisitor::Pre(const parser::InterfaceStmt
&x
) {
3159 bool isAbstract
{std::holds_alternative
<parser::Abstract
>(x
.u
)};
3160 genericInfo_
.emplace(/*isInterface*/ true, isAbstract
);
3161 return BeginAttrs();
3164 void InterfaceVisitor::Post(const parser::InterfaceStmt
&) { EndAttrs(); }
3166 void InterfaceVisitor::Post(const parser::EndInterfaceStmt
&) {
3170 // Create a symbol in genericSymbol_ for this GenericSpec.
3171 bool InterfaceVisitor::Pre(const parser::GenericSpec
&x
) {
3172 if (auto *symbol
{FindInScope(GenericSpecInfo
{x
}.symbolName())}) {
3173 SetGenericSymbol(*symbol
);
3175 if (const auto *opr
{std::get_if
<parser::DefinedOperator
>(&x
.u
)}; opr
&&
3176 std::holds_alternative
<parser::DefinedOperator::IntrinsicOperator
>(
3178 context().set_anyDefinedIntrinsicOperator(true);
3183 bool InterfaceVisitor::Pre(const parser::ProcedureStmt
&x
) {
3185 Say("A PROCEDURE statement is only allowed in a generic interface block"_err_en_US
);
3188 auto kind
{std::get
<parser::ProcedureStmt::Kind
>(x
.t
)};
3189 const auto &names
{std::get
<std::list
<parser::Name
>>(x
.t
)};
3190 AddSpecificProcs(names
, kind
);
3194 bool InterfaceVisitor::Pre(const parser::GenericStmt
&) {
3195 genericInfo_
.emplace(/*isInterface*/ false);
3198 void InterfaceVisitor::Post(const parser::GenericStmt
&x
) {
3199 if (auto &accessSpec
{std::get
<std::optional
<parser::AccessSpec
>>(x
.t
)}) {
3200 SetExplicitAttr(*GetGenericInfo().symbol
, AccessSpecToAttr(*accessSpec
));
3202 const auto &names
{std::get
<std::list
<parser::Name
>>(x
.t
)};
3203 AddSpecificProcs(names
, ProcedureKind::Procedure
);
3207 bool InterfaceVisitor::inInterfaceBlock() const {
3208 return !genericInfo_
.empty() && GetGenericInfo().isInterface
;
3210 bool InterfaceVisitor::isGeneric() const {
3211 return !genericInfo_
.empty() && GetGenericInfo().symbol
;
3213 bool InterfaceVisitor::isAbstract() const {
3214 return !genericInfo_
.empty() && GetGenericInfo().isAbstract
;
3217 void InterfaceVisitor::AddSpecificProcs(
3218 const std::list
<parser::Name
> &names
, ProcedureKind kind
) {
3219 for (const auto &name
: names
) {
3220 specificProcs_
.emplace(
3221 GetGenericInfo().symbol
, std::make_pair(&name
, kind
));
3225 // By now we should have seen all specific procedures referenced by name in
3226 // this generic interface. Resolve those names to symbols.
3227 void InterfaceVisitor::ResolveSpecificsInGeneric(Symbol
&generic
) {
3228 auto &details
{generic
.get
<GenericDetails
>()};
3229 UnorderedSymbolSet symbolsSeen
;
3230 for (const Symbol
&symbol
: details
.specificProcs()) {
3231 symbolsSeen
.insert(symbol
.GetUltimate());
3233 auto range
{specificProcs_
.equal_range(&generic
)};
3234 for (auto it
{range
.first
}; it
!= range
.second
; ++it
) {
3235 const parser::Name
*name
{it
->second
.first
};
3236 auto kind
{it
->second
.second
};
3237 const auto *symbol
{FindSymbol(*name
)};
3239 Say(*name
, "Procedure '%s' not found"_err_en_US
);
3242 // Subtlety: when *symbol is a use- or host-association, the specific
3243 // procedure that is recorded in the GenericDetails below must be *symbol,
3244 // not the specific procedure shadowed by a generic, because that specific
3245 // procedure may be a symbol from another module and its name unavailable to
3246 // emit to a module file.
3247 const Symbol
&bypassed
{BypassGeneric(*symbol
)};
3248 const Symbol
&specific
{
3249 symbol
== &symbol
->GetUltimate() ? bypassed
: *symbol
};
3250 const Symbol
&ultimate
{bypassed
.GetUltimate()};
3251 ProcedureDefinitionClass defClass
{ClassifyProcedure(ultimate
)};
3252 if (defClass
== ProcedureDefinitionClass::Module
) {
3254 } else if (kind
== ProcedureKind::ModuleProcedure
) {
3255 Say(*name
, "'%s' is not a module procedure"_err_en_US
);
3259 case ProcedureDefinitionClass::Intrinsic
:
3260 case ProcedureDefinitionClass::External
:
3261 case ProcedureDefinitionClass::Internal
:
3262 case ProcedureDefinitionClass::Dummy
:
3263 case ProcedureDefinitionClass::Pointer
:
3265 case ProcedureDefinitionClass::None
:
3266 Say(*name
, "'%s' is not a procedure"_err_en_US
);
3270 "'%s' is not a procedure that can appear in a generic interface"_err_en_US
);
3274 if (symbolsSeen
.insert(ultimate
).second
/*true if added*/) {
3275 // When a specific procedure is a USE association, that association
3276 // is saved in the generic's specifics, not its ultimate symbol,
3277 // so that module file output of interfaces can distinguish them.
3278 details
.AddSpecificProc(specific
, name
->source
);
3279 } else if (&specific
== &ultimate
) {
3281 "Procedure '%s' is already specified in generic '%s'"_err_en_US
,
3282 name
->source
, MakeOpName(generic
.name()));
3285 "Procedure '%s' from module '%s' is already specified in generic '%s'"_err_en_US
,
3286 ultimate
.name(), ultimate
.owner().GetName().value(),
3287 MakeOpName(generic
.name()));
3290 specificProcs_
.erase(range
.first
, range
.second
);
3293 // Mixed interfaces are allowed by the standard.
3294 // If there is a derived type with the same name, they must all be functions.
3295 void InterfaceVisitor::CheckGenericProcedures(Symbol
&generic
) {
3296 ResolveSpecificsInGeneric(generic
);
3297 auto &details
{generic
.get
<GenericDetails
>()};
3298 if (auto *proc
{details
.CheckSpecific()}) {
3300 "'%s' should not be the name of both a generic interface and a"
3301 " procedure unless it is a specific procedure of the generic"_warn_en_US
};
3302 if (proc
->name().begin() > generic
.name().begin()) {
3303 Say(proc
->name(), std::move(msg
));
3305 Say(generic
.name(), std::move(msg
));
3308 auto &specifics
{details
.specificProcs()};
3309 if (specifics
.empty()) {
3310 if (details
.derivedType()) {
3311 generic
.set(Symbol::Flag::Function
);
3315 const Symbol
&firstSpecific
{specifics
.front()};
3316 bool isFunction
{firstSpecific
.test(Symbol::Flag::Function
)};
3318 for (const Symbol
&specific
: specifics
) {
3319 if (isFunction
!= specific
.test(Symbol::Flag::Function
)) { // C1514
3320 auto &msg
{Say(generic
.name(),
3321 "Generic interface '%s' has both a function and a subroutine"_warn_en_US
)};
3323 msg
.Attach(firstSpecific
.name(), "Function declaration"_en_US
);
3324 msg
.Attach(specific
.name(), "Subroutine declaration"_en_US
);
3326 msg
.Attach(firstSpecific
.name(), "Subroutine declaration"_en_US
);
3327 msg
.Attach(specific
.name(), "Function declaration"_en_US
);
3334 if (!isFunction
&& details
.derivedType()) {
3335 SayDerivedType(generic
.name(),
3336 "Generic interface '%s' may only contain functions due to derived type"
3337 " with same name"_err_en_US
,
3338 *details
.derivedType()->GetUltimate().scope());
3341 generic
.set(isFunction
? Symbol::Flag::Function
: Symbol::Flag::Subroutine
);
3345 // SubprogramVisitor implementation
3347 // Return false if it is actually an assignment statement.
3348 bool SubprogramVisitor::HandleStmtFunction(const parser::StmtFunctionStmt
&x
) {
3349 const auto &name
{std::get
<parser::Name
>(x
.t
)};
3350 const DeclTypeSpec
*resultType
{nullptr};
3351 // Look up name: provides return type or tells us if it's an array
3352 if (auto *symbol
{FindSymbol(name
)}) {
3353 auto *details
{symbol
->detailsIf
<EntityDetails
>()};
3354 if (!details
|| symbol
->has
<ObjectEntityDetails
>() ||
3355 symbol
->has
<ProcEntityDetails
>()) {
3356 badStmtFuncFound_
= true;
3359 // TODO: check that attrs are compatible with stmt func
3360 resultType
= details
->type();
3361 symbol
->details() = UnknownDetails
{}; // will be replaced below
3363 if (badStmtFuncFound_
) {
3364 Say(name
, "'%s' has not been declared as an array"_err_en_US
);
3367 auto &symbol
{PushSubprogramScope(name
, Symbol::Flag::Function
)};
3368 symbol
.set(Symbol::Flag::StmtFunction
);
3369 EraseSymbol(symbol
); // removes symbol added by PushSubprogramScope
3370 auto &details
{symbol
.get
<SubprogramDetails
>()};
3371 for (const auto &dummyName
: std::get
<std::list
<parser::Name
>>(x
.t
)) {
3372 ObjectEntityDetails dummyDetails
{true};
3373 if (auto *dummySymbol
{FindInScope(currScope().parent(), dummyName
)}) {
3374 if (auto *d
{dummySymbol
->detailsIf
<EntityDetails
>()}) {
3376 dummyDetails
.set_type(*d
->type());
3380 Symbol
&dummy
{MakeSymbol(dummyName
, std::move(dummyDetails
))};
3381 ApplyImplicitRules(dummy
);
3382 details
.add_dummyArg(dummy
);
3384 ObjectEntityDetails resultDetails
;
3386 resultDetails
.set_type(*resultType
);
3388 resultDetails
.set_funcResult(true);
3389 Symbol
&result
{MakeSymbol(name
, std::move(resultDetails
))};
3390 result
.flags().set(Symbol::Flag::StmtFunction
);
3391 ApplyImplicitRules(result
);
3392 details
.set_result(result
);
3393 // The analysis of the expression that constitutes the body of the
3394 // statement function is deferred to FinishSpecificationPart() so that
3395 // all declarations and implicit typing are complete.
3400 bool SubprogramVisitor::Pre(const parser::Suffix
&suffix
) {
3401 if (suffix
.resultName
) {
3402 if (IsFunction(currScope())) {
3403 if (FuncResultStack::FuncInfo
* info
{funcResultStack().Top()}) {
3404 if (info
->inFunctionStmt
) {
3405 info
->resultName
= &suffix
.resultName
.value();
3407 // will check the result name in Post(EntryStmt)
3411 Message
&msg
{Say(*suffix
.resultName
,
3412 "RESULT(%s) may appear only in a function"_err_en_US
)};
3413 if (const Symbol
* subprogram
{InclusiveScope().symbol()}) {
3414 msg
.Attach(subprogram
->name(), "Containing subprogram"_en_US
);
3418 // LanguageBindingSpec deferred to Post(EntryStmt) or, for FunctionStmt,
3419 // all the way to EndSubprogram().
3423 bool SubprogramVisitor::Pre(const parser::PrefixSpec
&x
) {
3424 // Save this to process after UseStmt and ImplicitPart
3425 if (const auto *parsedType
{std::get_if
<parser::DeclarationTypeSpec
>(&x
.u
)}) {
3426 FuncResultStack::FuncInfo
&info
{DEREF(funcResultStack().Top())};
3427 if (info
.parsedType
) { // C1543
3428 Say(currStmtSource().value(),
3429 "FUNCTION prefix cannot specify the type more than once"_err_en_US
);
3432 info
.parsedType
= parsedType
;
3433 info
.source
= currStmtSource();
3441 bool SubprogramVisitor::Pre(const parser::InterfaceBody::Subroutine
&x
) {
3442 const auto &name
{std::get
<parser::Name
>(
3443 std::get
<parser::Statement
<parser::SubroutineStmt
>>(x
.t
).statement
.t
)};
3444 return BeginSubprogram(name
, Symbol::Flag::Subroutine
);
3446 void SubprogramVisitor::Post(const parser::InterfaceBody::Subroutine
&x
) {
3447 const auto &stmt
{std::get
<parser::Statement
<parser::SubroutineStmt
>>(x
.t
)};
3448 EndSubprogram(stmt
.source
,
3449 &std::get
<std::optional
<parser::LanguageBindingSpec
>>(stmt
.statement
.t
));
3451 bool SubprogramVisitor::Pre(const parser::InterfaceBody::Function
&x
) {
3452 const auto &name
{std::get
<parser::Name
>(
3453 std::get
<parser::Statement
<parser::FunctionStmt
>>(x
.t
).statement
.t
)};
3454 return BeginSubprogram(name
, Symbol::Flag::Function
);
3456 void SubprogramVisitor::Post(const parser::InterfaceBody::Function
&x
) {
3457 const auto &stmt
{std::get
<parser::Statement
<parser::FunctionStmt
>>(x
.t
)};
3458 const auto &maybeSuffix
{
3459 std::get
<std::optional
<parser::Suffix
>>(stmt
.statement
.t
)};
3460 EndSubprogram(stmt
.source
, maybeSuffix
? &maybeSuffix
->binding
: nullptr);
3463 bool SubprogramVisitor::Pre(const parser::SubroutineStmt
&stmt
) {
3465 Walk(std::get
<std::list
<parser::PrefixSpec
>>(stmt
.t
));
3466 Walk(std::get
<parser::Name
>(stmt
.t
));
3467 Walk(std::get
<std::list
<parser::DummyArg
>>(stmt
.t
));
3468 // Don't traverse the LanguageBindingSpec now; it's deferred to EndSubprogram.
3469 Symbol
&symbol
{PostSubprogramStmt()};
3470 SubprogramDetails
&details
{symbol
.get
<SubprogramDetails
>()};
3471 for (const auto &dummyArg
: std::get
<std::list
<parser::DummyArg
>>(stmt
.t
)) {
3472 if (const auto *dummyName
{std::get_if
<parser::Name
>(&dummyArg
.u
)}) {
3473 CreateDummyArgument(details
, *dummyName
);
3475 details
.add_alternateReturn();
3480 bool SubprogramVisitor::Pre(const parser::FunctionStmt
&) {
3481 FuncResultStack::FuncInfo
&info
{DEREF(funcResultStack().Top())};
3482 CHECK(!info
.inFunctionStmt
);
3483 info
.inFunctionStmt
= true;
3484 return BeginAttrs();
3486 bool SubprogramVisitor::Pre(const parser::EntryStmt
&) { return BeginAttrs(); }
3488 void SubprogramVisitor::Post(const parser::FunctionStmt
&stmt
) {
3489 const auto &name
{std::get
<parser::Name
>(stmt
.t
)};
3490 Symbol
&symbol
{PostSubprogramStmt()};
3491 SubprogramDetails
&details
{symbol
.get
<SubprogramDetails
>()};
3492 for (const auto &dummyName
: std::get
<std::list
<parser::Name
>>(stmt
.t
)) {
3493 CreateDummyArgument(details
, dummyName
);
3495 const parser::Name
*funcResultName
;
3496 FuncResultStack::FuncInfo
&info
{DEREF(funcResultStack().Top())};
3497 CHECK(info
.inFunctionStmt
);
3498 info
.inFunctionStmt
= false;
3499 bool distinctResultName
{
3500 info
.resultName
&& info
.resultName
->source
!= name
.source
};
3501 if (distinctResultName
) {
3502 // Note that RESULT is ignored if it has the same name as the function.
3503 // The symbol created by PushScope() is retained as a place-holder
3504 // for error detection.
3505 funcResultName
= info
.resultName
;
3507 EraseSymbol(name
); // was added by PushScope()
3508 funcResultName
= &name
;
3510 if (details
.isFunction()) {
3511 CHECK(context().HasError(currScope().symbol()));
3513 // RESULT(x) can be the same explicitly-named RESULT(x) as an ENTRY
3515 Symbol
*result
{nullptr};
3516 if (distinctResultName
) {
3517 if (auto iter
{currScope().find(funcResultName
->source
)};
3518 iter
!= currScope().end()) {
3519 Symbol
&entryResult
{*iter
->second
};
3520 if (IsFunctionResult(entryResult
)) {
3521 result
= &entryResult
;
3526 Resolve(*funcResultName
, *result
);
3528 // add function result to function scope
3529 EntityDetails funcResultDetails
;
3530 funcResultDetails
.set_funcResult(true);
3531 result
= &MakeSymbol(*funcResultName
, std::move(funcResultDetails
));
3533 info
.resultSymbol
= result
;
3534 details
.set_result(*result
);
3537 if (info
.resultName
&& !distinctResultName
) {
3538 Say(info
.resultName
->source
,
3539 "The function name should not appear in RESULT, references to '%s' "
3540 "inside the function will be considered as references to the "
3541 "result only"_warn_en_US
,
3543 // RESULT name was ignored above, the only side effect from doing so will be
3544 // the inability to make recursive calls. The related parser::Name is still
3545 // resolved to the created function result symbol because every parser::Name
3546 // should be resolved to avoid internal errors.
3547 Resolve(*info
.resultName
, info
.resultSymbol
);
3549 name
.symbol
= &symbol
; // must not be function result symbol
3550 // Clear the RESULT() name now in case an ENTRY statement in the implicit-part
3551 // has a RESULT() suffix.
3552 info
.resultName
= nullptr;
3555 Symbol
&SubprogramVisitor::PostSubprogramStmt() {
3556 Symbol
&symbol
{*currScope().symbol()};
3557 SetExplicitAttrs(symbol
, EndAttrs());
3558 if (symbol
.attrs().test(Attr::MODULE
)) {
3559 symbol
.attrs().set(Attr::EXTERNAL
, false);
3560 symbol
.implicitAttrs().set(Attr::EXTERNAL
, false);
3565 void SubprogramVisitor::Post(const parser::EntryStmt
&stmt
) {
3566 if (const auto &suffix
{std::get
<std::optional
<parser::Suffix
>>(stmt
.t
)}) {
3567 Walk(suffix
->binding
);
3569 PostEntryStmt(stmt
);
3573 void SubprogramVisitor::CreateDummyArgument(
3574 SubprogramDetails
&details
, const parser::Name
&name
) {
3575 Symbol
*dummy
{FindInScope(name
)};
3577 if (IsDummy(*dummy
)) {
3578 if (dummy
->test(Symbol::Flag::EntryDummyArgument
)) {
3579 dummy
->set(Symbol::Flag::EntryDummyArgument
, false);
3582 "'%s' appears more than once as a dummy argument name in this subprogram"_err_en_US
,
3587 SayWithDecl(name
, *dummy
,
3588 "'%s' may not appear as a dummy argument name in this subprogram"_err_en_US
);
3592 dummy
= &MakeSymbol(name
, EntityDetails
{true});
3594 details
.add_dummyArg(DEREF(dummy
));
3597 void SubprogramVisitor::CreateEntry(
3598 const parser::EntryStmt
&stmt
, Symbol
&subprogram
) {
3599 const auto &entryName
{std::get
<parser::Name
>(stmt
.t
)};
3600 Scope
&outer
{currScope().parent()};
3601 Symbol::Flag subpFlag
{subprogram
.test(Symbol::Flag::Function
)
3602 ? Symbol::Flag::Function
3603 : Symbol::Flag::Subroutine
};
3605 const auto &suffix
{std::get
<std::optional
<parser::Suffix
>>(stmt
.t
)};
3606 bool hasGlobalBindingName
{outer
.IsGlobal() && suffix
&& suffix
->binding
&&
3607 suffix
->binding
->v
.has_value()};
3608 if (!hasGlobalBindingName
) {
3609 if (Symbol
* extant
{FindSymbol(outer
, entryName
)}) {
3610 if (!HandlePreviousCalls(entryName
, *extant
, subpFlag
)) {
3611 if (outer
.IsTopLevel()) {
3613 "'%s' is already defined as a global identifier"_err_en_US
,
3614 *extant
, "Previous definition of '%s'"_en_US
);
3616 SayAlreadyDeclared(entryName
, *extant
);
3620 attrs
= extant
->attrs();
3623 bool badResultName
{false};
3624 std::optional
<SourceName
> distinctResultName
;
3625 if (suffix
&& suffix
->resultName
&&
3626 suffix
->resultName
->source
!= entryName
.source
) {
3627 distinctResultName
= suffix
->resultName
->source
;
3628 const parser::Name
&resultName
{*suffix
->resultName
};
3629 if (resultName
.source
== subprogram
.name()) { // C1574
3630 Say2(resultName
.source
,
3631 "RESULT(%s) may not have the same name as the function"_err_en_US
,
3632 subprogram
, "Containing function"_en_US
);
3633 badResultName
= true;
3634 } else if (const Symbol
* extant
{FindSymbol(outer
, resultName
)}) { // C1574
3635 if (const auto *details
{extant
->detailsIf
<SubprogramDetails
>()}) {
3636 if (details
->entryScope() == &currScope()) {
3637 Say2(resultName
.source
,
3638 "RESULT(%s) may not have the same name as an ENTRY in the function"_err_en_US
,
3639 extant
->name(), "Conflicting ENTRY"_en_US
);
3640 badResultName
= true;
3645 if (outer
.IsModule() && !attrs
.test(Attr::PRIVATE
)) {
3646 attrs
.set(Attr::PUBLIC
);
3648 Symbol
*entrySymbol
{nullptr};
3649 if (hasGlobalBindingName
) {
3650 // Hide the entry's symbol in a new anonymous global scope so
3651 // that its name doesn't clash with anything.
3652 Symbol
&symbol
{MakeSymbol(outer
, context().GetTempName(outer
), Attrs
{})};
3653 symbol
.set_details(MiscDetails
{MiscDetails::Kind::ScopeName
});
3654 Scope
&hidden
{outer
.MakeScope(Scope::Kind::Global
, &symbol
)};
3655 entrySymbol
= &MakeSymbol(hidden
, entryName
.source
, attrs
);
3657 entrySymbol
= FindInScope(outer
, entryName
.source
);
3659 if (auto *generic
{entrySymbol
->detailsIf
<GenericDetails
>()}) {
3660 if (auto *specific
{generic
->specific()}) {
3661 // Forward reference to ENTRY from a generic interface
3662 entrySymbol
= specific
;
3663 CheckDuplicatedAttrs(entryName
.source
, *entrySymbol
, attrs
);
3664 SetExplicitAttrs(*entrySymbol
, attrs
);
3668 entrySymbol
= &MakeSymbol(outer
, entryName
.source
, attrs
);
3671 SubprogramDetails entryDetails
;
3672 entryDetails
.set_entryScope(currScope());
3673 entrySymbol
->set(subpFlag
);
3674 if (subpFlag
== Symbol::Flag::Function
) {
3675 Symbol
*result
{nullptr};
3676 EntityDetails resultDetails
;
3677 resultDetails
.set_funcResult(true);
3678 if (distinctResultName
) {
3679 if (!badResultName
) {
3680 // RESULT(x) can be the same explicitly-named RESULT(x) as
3681 // the enclosing function or another ENTRY.
3682 if (auto iter
{currScope().find(suffix
->resultName
->source
)};
3683 iter
!= currScope().end()) {
3684 result
= &*iter
->second
;
3687 result
= &MakeSymbol(
3688 *distinctResultName
, Attrs
{}, std::move(resultDetails
));
3690 Resolve(*suffix
->resultName
, *result
);
3693 result
= &MakeSymbol(entryName
.source
, Attrs
{}, std::move(resultDetails
));
3696 entryDetails
.set_result(*result
);
3699 if (subpFlag
== Symbol::Flag::Subroutine
||
3700 (distinctResultName
&& !badResultName
)) {
3701 Symbol
&assoc
{MakeSymbol(entryName
.source
)};
3702 assoc
.set_details(HostAssocDetails
{*entrySymbol
});
3703 assoc
.set(Symbol::Flag::Subroutine
);
3705 Resolve(entryName
, *entrySymbol
);
3706 std::set
<SourceName
> dummies
;
3707 for (const auto &dummyArg
: std::get
<std::list
<parser::DummyArg
>>(stmt
.t
)) {
3708 if (const auto *dummyName
{std::get_if
<parser::Name
>(&dummyArg
.u
)}) {
3709 auto pair
{dummies
.insert(dummyName
->source
)};
3712 "'%s' appears more than once as a dummy argument name in this ENTRY statement"_err_en_US
,
3716 Symbol
*dummy
{FindInScope(*dummyName
)};
3718 if (!IsDummy(*dummy
)) {
3719 evaluate::AttachDeclaration(
3721 "'%s' may not appear as a dummy argument name in this ENTRY statement"_err_en_US
,
3727 dummy
= &MakeSymbol(*dummyName
, EntityDetails
{true});
3728 dummy
->set(Symbol::Flag::EntryDummyArgument
);
3730 entryDetails
.add_dummyArg(DEREF(dummy
));
3731 } else if (subpFlag
== Symbol::Flag::Function
) { // C1573
3733 "ENTRY in a function may not have an alternate return dummy argument"_err_en_US
);
3736 entryDetails
.add_alternateReturn();
3739 entrySymbol
->set_details(std::move(entryDetails
));
3742 void SubprogramVisitor::PostEntryStmt(const parser::EntryStmt
&stmt
) {
3743 // The entry symbol should have already been created and resolved
3744 // in CreateEntry(), called by BeginSubprogram(), with one exception (below).
3745 const auto &name
{std::get
<parser::Name
>(stmt
.t
)};
3746 Scope
&inclusiveScope
{InclusiveScope()};
3748 if (inclusiveScope
.kind() != Scope::Kind::Subprogram
) {
3750 "ENTRY '%s' may appear only in a subroutine or function"_err_en_US
,
3752 } else if (FindSeparateModuleSubprogramInterface(inclusiveScope
.symbol())) {
3754 "ENTRY '%s' may not appear in a separate module procedure"_err_en_US
,
3757 // C1571 - entry is nested, so was not put into the program tree; error
3758 // is emitted from MiscChecker in semantics.cpp.
3762 Symbol
&entrySymbol
{*name
.symbol
};
3763 if (context().HasError(entrySymbol
)) {
3766 if (!entrySymbol
.has
<SubprogramDetails
>()) {
3767 SayAlreadyDeclared(name
, entrySymbol
);
3770 SubprogramDetails
&entryDetails
{entrySymbol
.get
<SubprogramDetails
>()};
3771 CHECK(entryDetails
.entryScope() == &inclusiveScope
);
3772 entrySymbol
.attrs() |= GetAttrs();
3773 SetBindNameOn(entrySymbol
);
3774 for (const auto &dummyArg
: std::get
<std::list
<parser::DummyArg
>>(stmt
.t
)) {
3775 if (const auto *dummyName
{std::get_if
<parser::Name
>(&dummyArg
.u
)}) {
3776 if (Symbol
* dummy
{FindInScope(*dummyName
)}) {
3777 if (dummy
->test(Symbol::Flag::EntryDummyArgument
)) {
3778 const auto *subp
{dummy
->detailsIf
<SubprogramDetails
>()};
3779 if (subp
&& subp
->isInterface()) { // ok
3780 } else if (!dummy
->has
<EntityDetails
>() &&
3781 !dummy
->has
<ObjectEntityDetails
>() &&
3782 !dummy
->has
<ProcEntityDetails
>()) {
3783 SayWithDecl(*dummyName
, *dummy
,
3784 "ENTRY dummy argument '%s' was previously declared as an item that may not be used as a dummy argument"_err_en_US
);
3786 dummy
->set(Symbol::Flag::EntryDummyArgument
, false);
3793 Symbol
*ScopeHandler::FindSeparateModuleProcedureInterface(
3794 const parser::Name
&name
) {
3795 auto *symbol
{FindSymbol(name
)};
3796 if (symbol
&& symbol
->has
<SubprogramNameDetails
>()) {
3797 const Scope
*parent
{nullptr};
3798 if (currScope().IsSubmodule()) {
3799 parent
= currScope().symbol()->get
<ModuleDetails
>().parent();
3801 symbol
= parent
? FindSymbol(*parent
, name
) : nullptr;
3804 if (auto *generic
{symbol
->detailsIf
<GenericDetails
>()}) {
3805 symbol
= generic
->specific();
3808 if (const Symbol
* defnIface
{FindSeparateModuleSubprogramInterface(symbol
)}) {
3809 // Error recovery in case of multiple definitions
3810 symbol
= const_cast<Symbol
*>(defnIface
);
3812 if (!IsSeparateModuleProcedureInterface(symbol
)) {
3813 Say(name
, "'%s' was not declared a separate module procedure"_err_en_US
);
3819 // A subprogram declared with MODULE PROCEDURE
3820 bool SubprogramVisitor::BeginMpSubprogram(const parser::Name
&name
) {
3821 Symbol
*symbol
{FindSeparateModuleProcedureInterface(name
)};
3825 if (symbol
->owner() == currScope() && symbol
->scope()) {
3826 // This is a MODULE PROCEDURE whose interface appears in its host.
3827 // Convert the module procedure's interface into a subprogram.
3828 SetScope(DEREF(symbol
->scope()));
3829 symbol
->get
<SubprogramDetails
>().set_isInterface(false);
3831 // Copy the interface into a new subprogram scope.
3833 Symbol
&newSymbol
{MakeSymbol(name
, SubprogramDetails
{})};
3834 PushScope(Scope::Kind::Subprogram
, &newSymbol
);
3835 newSymbol
.get
<SubprogramDetails
>().set_moduleInterface(*symbol
);
3836 newSymbol
.attrs() |= symbol
->attrs();
3837 newSymbol
.set(symbol
->test(Symbol::Flag::Subroutine
)
3838 ? Symbol::Flag::Subroutine
3839 : Symbol::Flag::Function
);
3840 MapSubprogramToNewSymbols(*symbol
, newSymbol
, currScope());
3845 // A subprogram or interface declared with SUBROUTINE or FUNCTION
3846 bool SubprogramVisitor::BeginSubprogram(const parser::Name
&name
,
3847 Symbol::Flag subpFlag
, bool hasModulePrefix
,
3848 const parser::LanguageBindingSpec
*bindingSpec
,
3849 const ProgramTree::EntryStmtList
*entryStmts
) {
3850 if (hasModulePrefix
&& currScope().IsGlobal()) { // C1547
3852 "'%s' is a MODULE procedure which must be declared within a "
3853 "MODULE or SUBMODULE"_err_en_US
);
3856 Symbol
*moduleInterface
{nullptr};
3857 if (hasModulePrefix
&& !inInterfaceBlock()) {
3858 moduleInterface
= FindSeparateModuleProcedureInterface(name
);
3859 if (moduleInterface
&& &moduleInterface
->owner() == &currScope()) {
3860 // Subprogram is MODULE FUNCTION or MODULE SUBROUTINE with an interface
3861 // previously defined in the same scope.
3865 Symbol
&newSymbol
{PushSubprogramScope(name
, subpFlag
, bindingSpec
)};
3866 if (moduleInterface
) {
3867 newSymbol
.get
<SubprogramDetails
>().set_moduleInterface(*moduleInterface
);
3868 if (moduleInterface
->attrs().test(Attr::PRIVATE
)) {
3869 SetImplicitAttr(newSymbol
, Attr::PRIVATE
);
3870 } else if (moduleInterface
->attrs().test(Attr::PUBLIC
)) {
3871 SetImplicitAttr(newSymbol
, Attr::PUBLIC
);
3875 for (const auto &ref
: *entryStmts
) {
3876 CreateEntry(*ref
, newSymbol
);
3882 void SubprogramVisitor::HandleLanguageBinding(Symbol
*symbol
,
3883 std::optional
<parser::CharBlock
> stmtSource
,
3884 const std::optional
<parser::LanguageBindingSpec
> *binding
) {
3885 if (binding
&& *binding
&& symbol
) {
3886 // Finally process the BIND(C,NAME=name) now that symbols in the name
3887 // expression will resolve to local names if needed.
3888 auto flagRestorer
{common::ScopedSet(inSpecificationPart_
, false)};
3889 auto originalStmtSource
{messageHandler().currStmtSource()};
3890 messageHandler().set_currStmtSource(stmtSource
);
3893 SetBindNameOn(*symbol
);
3894 symbol
->attrs() |= EndAttrs();
3895 messageHandler().set_currStmtSource(originalStmtSource
);
3899 void SubprogramVisitor::EndSubprogram(
3900 std::optional
<parser::CharBlock
> stmtSource
,
3901 const std::optional
<parser::LanguageBindingSpec
> *binding
,
3902 const ProgramTree::EntryStmtList
*entryStmts
) {
3903 HandleLanguageBinding(currScope().symbol(), stmtSource
, binding
);
3905 for (const auto &ref
: *entryStmts
) {
3906 const parser::EntryStmt
&entryStmt
{*ref
};
3907 if (const auto &suffix
{
3908 std::get
<std::optional
<parser::Suffix
>>(entryStmt
.t
)}) {
3909 const auto &name
{std::get
<parser::Name
>(entryStmt
.t
)};
3910 HandleLanguageBinding(name
.symbol
, name
.source
, &suffix
->binding
);
3917 bool SubprogramVisitor::HandlePreviousCalls(
3918 const parser::Name
&name
, Symbol
&symbol
, Symbol::Flag subpFlag
) {
3919 // If the extant symbol is a generic, check its homonymous specific
3920 // procedure instead if it has one.
3921 if (auto *generic
{symbol
.detailsIf
<GenericDetails
>()}) {
3922 return generic
->specific() &&
3923 HandlePreviousCalls(name
, *generic
->specific(), subpFlag
);
3924 } else if (const auto *proc
{symbol
.detailsIf
<ProcEntityDetails
>()}; proc
&&
3926 !symbol
.attrs().HasAny(Attrs
{Attr::INTRINSIC
, Attr::POINTER
})) {
3927 // There's a symbol created for previous calls to this subprogram or
3928 // ENTRY's name. We have to replace that symbol in situ to avoid the
3929 // obligation to rewrite symbol pointers in the parse tree.
3930 if (!symbol
.test(subpFlag
)) {
3931 // External statements issue an explicit EXTERNAL attribute.
3932 if (symbol
.attrs().test(Attr::EXTERNAL
) &&
3933 !symbol
.implicitAttrs().test(Attr::EXTERNAL
)) {
3934 // Warn if external statement previously declared.
3936 "EXTERNAL attribute was already specified on '%s'"_warn_en_US
);
3939 subpFlag
== Symbol::Flag::Function
3940 ? "'%s' was previously called as a subroutine"_err_en_US
3941 : "'%s' was previously called as a function"_err_en_US
,
3942 symbol
, "Previous call of '%s'"_en_US
);
3945 EntityDetails entity
;
3947 entity
.set_type(*proc
->type());
3949 symbol
.details() = std::move(entity
);
3952 return symbol
.has
<UnknownDetails
>() || symbol
.has
<SubprogramNameDetails
>();
3956 void SubprogramVisitor::CheckExtantProc(
3957 const parser::Name
&name
, Symbol::Flag subpFlag
) {
3958 if (auto *prev
{FindSymbol(name
)}) {
3959 if (IsDummy(*prev
)) {
3960 } else if (auto *entity
{prev
->detailsIf
<EntityDetails
>()};
3961 IsPointer(*prev
) && entity
&& !entity
->type()) {
3962 // POINTER attribute set before interface
3963 } else if (inInterfaceBlock() && currScope() != prev
->owner()) {
3964 // Procedures in an INTERFACE block do not resolve to symbols
3965 // in scopes between the global scope and the current scope.
3966 } else if (!HandlePreviousCalls(name
, *prev
, subpFlag
)) {
3967 SayAlreadyDeclared(name
, *prev
);
3972 Symbol
&SubprogramVisitor::PushSubprogramScope(const parser::Name
&name
,
3973 Symbol::Flag subpFlag
, const parser::LanguageBindingSpec
*bindingSpec
) {
3974 Symbol
*symbol
{GetSpecificFromGeneric(name
)};
3976 if (bindingSpec
&& currScope().IsGlobal() && bindingSpec
->v
) {
3977 // Create this new top-level subprogram with a binding label
3978 // in a new global scope, so that its symbol's name won't clash
3979 // with another symbol that has a distinct binding label.
3980 PushScope(Scope::Kind::Global
,
3981 &MakeSymbol(context().GetTempName(currScope()), Attrs
{},
3982 MiscDetails
{MiscDetails::Kind::ScopeName
}));
3984 CheckExtantProc(name
, subpFlag
);
3985 symbol
= &MakeSymbol(name
, SubprogramDetails
{});
3987 symbol
->ReplaceName(name
.source
);
3988 symbol
->set(subpFlag
);
3989 PushScope(Scope::Kind::Subprogram
, symbol
);
3990 if (subpFlag
== Symbol::Flag::Function
) {
3991 funcResultStack().Push(currScope());
3993 if (inInterfaceBlock()) {
3994 auto &details
{symbol
->get
<SubprogramDetails
>()};
3995 details
.set_isInterface();
3997 SetExplicitAttr(*symbol
, Attr::ABSTRACT
);
3999 MakeExternal(*symbol
);
4002 Symbol
&genericSymbol
{GetGenericSymbol()};
4003 if (auto *details
{genericSymbol
.detailsIf
<GenericDetails
>()}) {
4004 details
->AddSpecificProc(*symbol
, name
.source
);
4006 CHECK(context().HasError(genericSymbol
));
4009 set_inheritFromParent(false);
4011 FindSymbol(name
)->set(subpFlag
); // PushScope() created symbol
4015 void SubprogramVisitor::PushBlockDataScope(const parser::Name
&name
) {
4016 if (auto *prev
{FindSymbol(name
)}) {
4017 if (prev
->attrs().test(Attr::EXTERNAL
) && prev
->has
<ProcEntityDetails
>()) {
4018 if (prev
->test(Symbol::Flag::Subroutine
) ||
4019 prev
->test(Symbol::Flag::Function
)) {
4020 Say2(name
, "BLOCK DATA '%s' has been called"_err_en_US
, *prev
,
4021 "Previous call of '%s'"_en_US
);
4026 if (name
.source
.empty()) {
4027 // Don't let unnamed BLOCK DATA conflict with unnamed PROGRAM
4028 PushScope(Scope::Kind::BlockData
, nullptr);
4030 PushScope(Scope::Kind::BlockData
, &MakeSymbol(name
, SubprogramDetails
{}));
4034 // If name is a generic, return specific subprogram with the same name.
4035 Symbol
*SubprogramVisitor::GetSpecificFromGeneric(const parser::Name
&name
) {
4036 // Search for the name but don't resolve it
4037 if (auto *symbol
{currScope().FindSymbol(name
.source
)}) {
4038 if (symbol
->has
<SubprogramNameDetails
>()) {
4039 if (inInterfaceBlock()) {
4040 // Subtle: clear any MODULE flag so that the new interface
4041 // symbol doesn't inherit it and ruin the ability to check it.
4042 symbol
->attrs().reset(Attr::MODULE
);
4044 } else if (auto *details
{symbol
->detailsIf
<GenericDetails
>()}) {
4045 // found generic, want specific procedure
4046 auto *specific
{details
->specific()};
4047 if (inInterfaceBlock()) {
4049 // Defining an interface in a generic of the same name which is
4050 // already shadowing another procedure. In some cases, the shadowed
4051 // procedure is about to be replaced.
4052 if (specific
->has
<SubprogramNameDetails
>() &&
4053 specific
->attrs().test(Attr::MODULE
)) {
4054 // The shadowed procedure is a separate module procedure that is
4055 // actually defined later in this (sub)module.
4056 // Define its interface now as a new symbol.
4058 } else if (&specific
->owner() != &symbol
->owner()) {
4059 // The shadowed procedure was from an enclosing scope and will be
4060 // overridden by this interface definition.
4064 details
->clear_specific();
4066 } else if (const auto *dType
{details
->derivedType()}) {
4067 if (&dType
->owner() != &symbol
->owner()) {
4068 // The shadowed derived type was from an enclosing scope and
4069 // will be overridden by this interface definition.
4070 details
->clear_derivedType();
4076 &currScope().MakeSymbol(name
.source
, Attrs
{}, SubprogramDetails
{});
4077 if (details
->derivedType()) {
4078 // A specific procedure with the same name as a derived type
4079 SayAlreadyDeclared(name
, *details
->derivedType());
4081 details
->set_specific(Resolve(name
, *specific
));
4083 } else if (isGeneric()) {
4084 SayAlreadyDeclared(name
, *specific
);
4086 if (specific
->has
<SubprogramNameDetails
>()) {
4087 specific
->set_details(Details
{SubprogramDetails
{}});
4095 // DeclarationVisitor implementation
4097 bool DeclarationVisitor::BeginDecl() {
4098 BeginDeclTypeSpec();
4100 return BeginAttrs();
4102 void DeclarationVisitor::EndDecl() {
4108 bool DeclarationVisitor::CheckUseError(const parser::Name
&name
) {
4109 const auto *details
{
4110 name
.symbol
? name
.symbol
->detailsIf
<UseErrorDetails
>() : nullptr};
4114 Message
&msg
{Say(name
, "Reference to '%s' is ambiguous"_err_en_US
)};
4115 for (const auto &[location
, module
] : details
->occurrences()) {
4116 msg
.Attach(location
, "'%s' was use-associated from module '%s'"_en_US
,
4117 name
.source
, module
->GetName().value());
4119 context().SetError(*name
.symbol
);
4123 // Report error if accessibility of symbol doesn't match isPrivate.
4124 void DeclarationVisitor::CheckAccessibility(
4125 const SourceName
&name
, bool isPrivate
, Symbol
&symbol
) {
4126 if (symbol
.attrs().test(Attr::PRIVATE
) != isPrivate
) {
4128 "'%s' does not have the same accessibility as its previous declaration"_err_en_US
,
4129 symbol
, "Previous declaration of '%s'"_en_US
);
4133 void DeclarationVisitor::Post(const parser::TypeDeclarationStmt
&) {
4137 void DeclarationVisitor::Post(const parser::DimensionStmt::Declaration
&x
) {
4138 DeclareObjectEntity(std::get
<parser::Name
>(x
.t
));
4140 void DeclarationVisitor::Post(const parser::CodimensionDecl
&x
) {
4141 DeclareObjectEntity(std::get
<parser::Name
>(x
.t
));
4144 bool DeclarationVisitor::Pre(const parser::Initialization
&) {
4145 // Defer inspection of initializers to Initialization() so that the
4146 // symbol being initialized will be available within the initialization
4151 void DeclarationVisitor::Post(const parser::EntityDecl
&x
) {
4152 const auto &name
{std::get
<parser::ObjectName
>(x
.t
)};
4153 Attrs attrs
{attrs_
? HandleSaveName(name
.source
, *attrs_
) : Attrs
{}};
4154 Symbol
&symbol
{DeclareUnknownEntity(name
, attrs
)};
4155 symbol
.ReplaceName(name
.source
);
4156 if (const auto &init
{std::get
<std::optional
<parser::Initialization
>>(x
.t
)}) {
4157 ConvertToObjectEntity(symbol
) || ConvertToProcEntity(symbol
);
4159 Symbol::Flag::EntryDummyArgument
, false); // forestall excessive errors
4160 Initialization(name
, *init
, false);
4161 } else if (attrs
.test(Attr::PARAMETER
)) { // C882, C883
4162 Say(name
, "Missing initialization for parameter '%s'"_err_en_US
);
4166 void DeclarationVisitor::Post(const parser::PointerDecl
&x
) {
4167 const auto &name
{std::get
<parser::Name
>(x
.t
)};
4168 if (const auto &deferredShapeSpecs
{
4169 std::get
<std::optional
<parser::DeferredShapeSpecList
>>(x
.t
)}) {
4170 CHECK(arraySpec().empty());
4172 set_arraySpec(AnalyzeDeferredShapeSpecList(context(), *deferredShapeSpecs
));
4173 Symbol
&symbol
{DeclareObjectEntity(name
, Attrs
{Attr::POINTER
})};
4174 symbol
.ReplaceName(name
.source
);
4177 if (const auto *symbol
{FindInScope(name
)}) {
4178 const auto *subp
{symbol
->detailsIf
<SubprogramDetails
>()};
4179 if (!symbol
->has
<UseDetails
>() && // error caught elsewhere
4180 !symbol
->has
<ObjectEntityDetails
>() &&
4181 !symbol
->has
<ProcEntityDetails
>() &&
4182 !symbol
->CanReplaceDetails(ObjectEntityDetails
{}) &&
4183 !symbol
->CanReplaceDetails(ProcEntityDetails
{}) &&
4184 !(subp
&& subp
->isInterface())) {
4185 Say(name
, "'%s' cannot have the POINTER attribute"_err_en_US
);
4188 HandleAttributeStmt(Attr::POINTER
, std::get
<parser::Name
>(x
.t
));
4192 bool DeclarationVisitor::Pre(const parser::BindEntity
&x
) {
4193 auto kind
{std::get
<parser::BindEntity::Kind
>(x
.t
)};
4194 auto &name
{std::get
<parser::Name
>(x
.t
)};
4196 if (kind
== parser::BindEntity::Kind::Object
) {
4197 symbol
= &HandleAttributeStmt(Attr::BIND_C
, name
);
4199 symbol
= &MakeCommonBlockSymbol(name
);
4200 SetExplicitAttr(*symbol
, Attr::BIND_C
);
4203 // Some entities such as named constant or module name need to checked
4204 // elsewhere. This is to skip the ICE caused by setting Bind name for non-name
4205 // things such as data type and also checks for procedures.
4206 if (symbol
->has
<CommonBlockDetails
>() || symbol
->has
<ObjectEntityDetails
>() ||
4207 symbol
->has
<EntityDetails
>()) {
4208 SetBindNameOn(*symbol
);
4211 "Only variable and named common block can be in BIND statement"_err_en_US
);
4215 bool DeclarationVisitor::Pre(const parser::OldParameterStmt
&x
) {
4216 inOldStyleParameterStmt_
= true;
4218 inOldStyleParameterStmt_
= false;
4221 bool DeclarationVisitor::Pre(const parser::NamedConstantDef
&x
) {
4222 auto &name
{std::get
<parser::NamedConstant
>(x
.t
).v
};
4223 auto &symbol
{HandleAttributeStmt(Attr::PARAMETER
, name
)};
4224 if (!ConvertToObjectEntity(symbol
) ||
4225 symbol
.test(Symbol::Flag::CrayPointer
) ||
4226 symbol
.test(Symbol::Flag::CrayPointee
)) {
4228 name
, symbol
, "PARAMETER attribute not allowed on '%s'"_err_en_US
);
4231 const auto &expr
{std::get
<parser::ConstantExpr
>(x
.t
)};
4232 auto &details
{symbol
.get
<ObjectEntityDetails
>()};
4233 if (inOldStyleParameterStmt_
) {
4234 // non-standard extension PARAMETER statement (no parentheses)
4236 auto folded
{EvaluateExpr(expr
)};
4237 if (details
.type()) {
4238 SayWithDecl(name
, symbol
,
4239 "Alternative style PARAMETER '%s' must not already have an explicit type"_err_en_US
);
4240 } else if (folded
) {
4241 auto at
{expr
.thing
.value().source
};
4242 if (evaluate::IsActuallyConstant(*folded
)) {
4243 if (const auto *type
{currScope().GetType(*folded
)}) {
4244 if (type
->IsPolymorphic()) {
4245 Say(at
, "The expression must not be polymorphic"_err_en_US
);
4246 } else if (auto shape
{ToArraySpec(
4247 GetFoldingContext(), evaluate::GetShape(*folded
))}) {
4248 // The type of the named constant is assumed from the expression.
4249 details
.set_type(*type
);
4250 details
.set_init(std::move(*folded
));
4251 details
.set_shape(std::move(*shape
));
4253 Say(at
, "The expression must have constant shape"_err_en_US
);
4256 Say(at
, "The expression must have a known type"_err_en_US
);
4259 Say(at
, "The expression must be a constant of known type"_err_en_US
);
4263 // standard-conforming PARAMETER statement (with parentheses)
4264 ApplyImplicitRules(symbol
);
4266 if (auto converted
{EvaluateNonPointerInitializer(
4267 symbol
, expr
, expr
.thing
.value().source
)}) {
4268 details
.set_init(std::move(*converted
));
4273 bool DeclarationVisitor::Pre(const parser::NamedConstant
&x
) {
4274 const parser::Name
&name
{x
.v
};
4275 if (!FindSymbol(name
)) {
4276 Say(name
, "Named constant '%s' not found"_err_en_US
);
4278 CheckUseError(name
);
4283 bool DeclarationVisitor::Pre(const parser::Enumerator
&enumerator
) {
4284 const parser::Name
&name
{std::get
<parser::NamedConstant
>(enumerator
.t
).v
};
4285 Symbol
*symbol
{FindInScope(name
)};
4286 if (symbol
&& !symbol
->has
<UnknownDetails
>()) {
4287 // Contrary to named constants appearing in a PARAMETER statement,
4288 // enumerator names should not have their type, dimension or any other
4289 // attributes defined before they are declared in the enumerator statement,
4290 // with the exception of accessibility.
4291 // This is not explicitly forbidden by the standard, but they are scalars
4292 // which type is left for the compiler to chose, so do not let users try to
4293 // tamper with that.
4294 SayAlreadyDeclared(name
, *symbol
);
4297 // Enumerators are treated as PARAMETER (section 7.6 paragraph (4))
4298 symbol
= &MakeSymbol(name
, Attrs
{Attr::PARAMETER
}, ObjectEntityDetails
{});
4299 symbol
->SetType(context().MakeNumericType(
4300 TypeCategory::Integer
, evaluate::CInteger::kind
));
4303 if (auto &init
{std::get
<std::optional
<parser::ScalarIntConstantExpr
>>(
4305 Walk(*init
); // Resolve names in expression before evaluation.
4306 if (auto value
{EvaluateInt64(context(), *init
)}) {
4307 // Cast all init expressions to C_INT so that they can then be
4308 // safely incremented (see 7.6 Note 2).
4309 enumerationState_
.value
= static_cast<int>(*value
);
4312 "Enumerator value could not be computed "
4313 "from the given expression"_err_en_US
);
4314 // Prevent resolution of next enumerators value
4315 enumerationState_
.value
= std::nullopt
;
4320 if (enumerationState_
.value
) {
4321 symbol
->get
<ObjectEntityDetails
>().set_init(SomeExpr
{
4322 evaluate::Expr
<evaluate::CInteger
>{*enumerationState_
.value
}});
4324 context().SetError(*symbol
);
4328 if (enumerationState_
.value
) {
4329 (*enumerationState_
.value
)++;
4334 void DeclarationVisitor::Post(const parser::EnumDef
&) {
4335 enumerationState_
= EnumeratorState
{};
4338 bool DeclarationVisitor::Pre(const parser::AccessSpec
&x
) {
4339 Attr attr
{AccessSpecToAttr(x
)};
4340 if (!NonDerivedTypeScope().IsModule()) { // C817
4341 Say(currStmtSource().value(),
4342 "%s attribute may only appear in the specification part of a module"_err_en_US
,
4343 EnumToString(attr
));
4349 bool DeclarationVisitor::Pre(const parser::AsynchronousStmt
&x
) {
4350 return HandleAttributeStmt(Attr::ASYNCHRONOUS
, x
.v
);
4352 bool DeclarationVisitor::Pre(const parser::ContiguousStmt
&x
) {
4353 return HandleAttributeStmt(Attr::CONTIGUOUS
, x
.v
);
4355 bool DeclarationVisitor::Pre(const parser::ExternalStmt
&x
) {
4356 HandleAttributeStmt(Attr::EXTERNAL
, x
.v
);
4357 for (const auto &name
: x
.v
) {
4358 auto *symbol
{FindSymbol(name
)};
4359 if (!ConvertToProcEntity(DEREF(symbol
))) {
4360 // Check if previous symbol is an interface.
4361 if (auto *details
{symbol
->detailsIf
<SubprogramDetails
>()}) {
4362 if (details
->isInterface()) {
4363 // Warn if interface previously declared.
4365 "EXTERNAL attribute was already specified on '%s'"_warn_en_US
);
4369 name
, *symbol
, "EXTERNAL attribute not allowed on '%s'"_err_en_US
);
4371 } else if (symbol
->attrs().test(Attr::INTRINSIC
)) { // C840
4373 "Symbol '%s' cannot have both INTRINSIC and EXTERNAL attributes"_err_en_US
,
4379 bool DeclarationVisitor::Pre(const parser::IntentStmt
&x
) {
4380 auto &intentSpec
{std::get
<parser::IntentSpec
>(x
.t
)};
4381 auto &names
{std::get
<std::list
<parser::Name
>>(x
.t
)};
4382 return CheckNotInBlock("INTENT") && // C1107
4383 HandleAttributeStmt(IntentSpecToAttr(intentSpec
), names
);
4385 bool DeclarationVisitor::Pre(const parser::IntrinsicStmt
&x
) {
4386 HandleAttributeStmt(Attr::INTRINSIC
, x
.v
);
4387 for (const auto &name
: x
.v
) {
4388 if (!IsIntrinsic(name
.source
, std::nullopt
)) {
4389 Say(name
.source
, "'%s' is not a known intrinsic procedure"_err_en_US
);
4391 auto &symbol
{DEREF(FindSymbol(name
))};
4392 if (symbol
.has
<GenericDetails
>()) {
4393 // Generic interface is extending intrinsic; ok
4394 } else if (!ConvertToProcEntity(symbol
)) {
4396 name
, symbol
, "INTRINSIC attribute not allowed on '%s'"_err_en_US
);
4397 } else if (symbol
.attrs().test(Attr::EXTERNAL
)) { // C840
4399 "Symbol '%s' cannot have both EXTERNAL and INTRINSIC attributes"_err_en_US
,
4401 } else if (symbol
.GetType()) {
4402 // These warnings are worded so that they should make sense in either
4405 "Explicit type declaration ignored for intrinsic function '%s'"_warn_en_US
,
4407 .Attach(name
.source
,
4408 "INTRINSIC statement for explicitly-typed '%s'"_en_US
,
4414 bool DeclarationVisitor::Pre(const parser::OptionalStmt
&x
) {
4415 return CheckNotInBlock("OPTIONAL") && // C1107
4416 HandleAttributeStmt(Attr::OPTIONAL
, x
.v
);
4418 bool DeclarationVisitor::Pre(const parser::ProtectedStmt
&x
) {
4419 return HandleAttributeStmt(Attr::PROTECTED
, x
.v
);
4421 bool DeclarationVisitor::Pre(const parser::ValueStmt
&x
) {
4422 return CheckNotInBlock("VALUE") && // C1107
4423 HandleAttributeStmt(Attr::VALUE
, x
.v
);
4425 bool DeclarationVisitor::Pre(const parser::VolatileStmt
&x
) {
4426 return HandleAttributeStmt(Attr::VOLATILE
, x
.v
);
4428 // Handle a statement that sets an attribute on a list of names.
4429 bool DeclarationVisitor::HandleAttributeStmt(
4430 Attr attr
, const std::list
<parser::Name
> &names
) {
4431 for (const auto &name
: names
) {
4432 HandleAttributeStmt(attr
, name
);
4436 Symbol
&DeclarationVisitor::HandleAttributeStmt(
4437 Attr attr
, const parser::Name
&name
) {
4438 auto *symbol
{FindInScope(name
)};
4439 if (attr
== Attr::ASYNCHRONOUS
|| attr
== Attr::VOLATILE
) {
4440 // these can be set on a symbol that is host-assoc or use-assoc
4442 (currScope().kind() == Scope::Kind::Subprogram
||
4443 currScope().kind() == Scope::Kind::BlockConstruct
)) {
4444 if (auto *hostSymbol
{FindSymbol(name
)}) {
4445 symbol
= &MakeHostAssocSymbol(name
, *hostSymbol
);
4448 } else if (symbol
&& symbol
->has
<UseDetails
>()) {
4449 Say(currStmtSource().value(),
4450 "Cannot change %s attribute on use-associated '%s'"_err_en_US
,
4451 EnumToString(attr
), name
.source
);
4455 symbol
= &MakeSymbol(name
, EntityDetails
{});
4457 if (CheckDuplicatedAttr(name
.source
, *symbol
, attr
)) {
4458 SetExplicitAttr(*symbol
, attr
);
4459 symbol
->attrs() = HandleSaveName(name
.source
, symbol
->attrs());
4464 bool DeclarationVisitor::CheckNotInBlock(const char *stmt
) {
4465 if (currScope().kind() == Scope::Kind::BlockConstruct
) {
4466 Say(MessageFormattedText
{
4467 "%s statement is not allowed in a BLOCK construct"_err_en_US
, stmt
});
4474 void DeclarationVisitor::Post(const parser::ObjectDecl
&x
) {
4475 CHECK(objectDeclAttr_
);
4476 const auto &name
{std::get
<parser::ObjectName
>(x
.t
)};
4477 DeclareObjectEntity(name
, Attrs
{*objectDeclAttr_
});
4480 // Declare an entity not yet known to be an object or proc.
4481 Symbol
&DeclarationVisitor::DeclareUnknownEntity(
4482 const parser::Name
&name
, Attrs attrs
) {
4483 if (!arraySpec().empty() || !coarraySpec().empty()) {
4484 return DeclareObjectEntity(name
, attrs
);
4486 Symbol
&symbol
{DeclareEntity
<EntityDetails
>(name
, attrs
)};
4487 if (auto *type
{GetDeclTypeSpec()}) {
4488 SetType(name
, *type
);
4490 charInfo_
.length
.reset();
4491 if (symbol
.attrs().test(Attr::EXTERNAL
)) {
4492 ConvertToProcEntity(symbol
);
4494 SetBindNameOn(symbol
);
4499 bool DeclarationVisitor::HasCycle(
4500 const Symbol
&procSymbol
, const Symbol
*interface
) {
4501 SourceOrderedSymbolSet procsInCycle
;
4502 procsInCycle
.insert(procSymbol
);
4504 if (procsInCycle
.count(*interface
) > 0) {
4505 for (const auto &procInCycle
: procsInCycle
) {
4506 Say(procInCycle
->name(),
4507 "The interface for procedure '%s' is recursively "
4508 "defined"_err_en_US
,
4509 procInCycle
->name());
4510 context().SetError(*procInCycle
);
4513 } else if (const auto *procDetails
{
4514 interface
->detailsIf
<ProcEntityDetails
>()}) {
4515 procsInCycle
.insert(*interface
);
4516 interface
= procDetails
->procInterface();
4524 Symbol
&DeclarationVisitor::DeclareProcEntity(
4525 const parser::Name
&name
, Attrs attrs
, const Symbol
*interface
) {
4526 Symbol
&symbol
{DeclareEntity
<ProcEntityDetails
>(name
, attrs
)};
4527 if (auto *details
{symbol
.detailsIf
<ProcEntityDetails
>()}) {
4528 if (details
->IsInterfaceSet()) {
4529 SayWithDecl(name
, symbol
,
4530 "The interface for procedure '%s' has already been "
4531 "declared"_err_en_US
);
4532 context().SetError(symbol
);
4533 } else if (HasCycle(symbol
, interface
)) {
4535 } else if (interface
) {
4536 details
->set_procInterface(*interface
);
4537 if (interface
->test(Symbol::Flag::Function
)) {
4538 symbol
.set(Symbol::Flag::Function
);
4539 } else if (interface
->test(Symbol::Flag::Subroutine
)) {
4540 symbol
.set(Symbol::Flag::Subroutine
);
4542 } else if (auto *type
{GetDeclTypeSpec()}) {
4543 SetType(name
, *type
);
4544 symbol
.set(Symbol::Flag::Function
);
4546 SetBindNameOn(symbol
);
4547 SetPassNameOn(symbol
);
4552 Symbol
&DeclarationVisitor::DeclareObjectEntity(
4553 const parser::Name
&name
, Attrs attrs
) {
4554 Symbol
&symbol
{DeclareEntity
<ObjectEntityDetails
>(name
, attrs
)};
4555 if (auto *details
{symbol
.detailsIf
<ObjectEntityDetails
>()}) {
4556 if (auto *type
{GetDeclTypeSpec()}) {
4557 SetType(name
, *type
);
4559 if (!arraySpec().empty()) {
4560 if (details
->IsArray()) {
4561 if (!context().HasError(symbol
)) {
4563 "The dimensions of '%s' have already been declared"_err_en_US
);
4564 context().SetError(symbol
);
4567 details
->set_shape(arraySpec());
4570 if (!coarraySpec().empty()) {
4571 if (details
->IsCoarray()) {
4572 if (!context().HasError(symbol
)) {
4574 "The codimensions of '%s' have already been declared"_err_en_US
);
4575 context().SetError(symbol
);
4578 details
->set_coshape(coarraySpec());
4581 SetBindNameOn(symbol
);
4585 charInfo_
.length
.reset();
4589 void DeclarationVisitor::Post(const parser::IntegerTypeSpec
&x
) {
4590 SetDeclTypeSpec(MakeNumericType(TypeCategory::Integer
, x
.v
));
4592 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Real
&x
) {
4593 SetDeclTypeSpec(MakeNumericType(TypeCategory::Real
, x
.kind
));
4595 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Complex
&x
) {
4596 SetDeclTypeSpec(MakeNumericType(TypeCategory::Complex
, x
.kind
));
4598 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Logical
&x
) {
4599 SetDeclTypeSpec(MakeLogicalType(x
.kind
));
4601 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Character
&) {
4602 if (!charInfo_
.length
) {
4603 charInfo_
.length
= ParamValue
{1, common::TypeParamAttr::Len
};
4605 if (!charInfo_
.kind
) {
4607 KindExpr
{context().GetDefaultKind(TypeCategory::Character
)};
4609 SetDeclTypeSpec(currScope().MakeCharacterType(
4610 std::move(*charInfo_
.length
), std::move(*charInfo_
.kind
)));
4613 void DeclarationVisitor::Post(const parser::CharSelector::LengthAndKind
&x
) {
4614 charInfo_
.kind
= EvaluateSubscriptIntExpr(x
.kind
);
4615 std::optional
<std::int64_t> intKind
{ToInt64(charInfo_
.kind
)};
4617 !context().targetCharacteristics().IsTypeEnabled(
4618 TypeCategory::Character
, *intKind
)) { // C715, C719
4619 Say(currStmtSource().value(),
4620 "KIND value (%jd) not valid for CHARACTER"_err_en_US
, *intKind
);
4621 charInfo_
.kind
= std::nullopt
; // prevent further errors
4624 charInfo_
.length
= GetParamValue(*x
.length
, common::TypeParamAttr::Len
);
4627 void DeclarationVisitor::Post(const parser::CharLength
&x
) {
4628 if (const auto *length
{std::get_if
<std::uint64_t>(&x
.u
)}) {
4629 charInfo_
.length
= ParamValue
{
4630 static_cast<ConstantSubscript
>(*length
), common::TypeParamAttr::Len
};
4632 charInfo_
.length
= GetParamValue(
4633 std::get
<parser::TypeParamValue
>(x
.u
), common::TypeParamAttr::Len
);
4636 void DeclarationVisitor::Post(const parser::LengthSelector
&x
) {
4637 if (const auto *param
{std::get_if
<parser::TypeParamValue
>(&x
.u
)}) {
4638 charInfo_
.length
= GetParamValue(*param
, common::TypeParamAttr::Len
);
4642 bool DeclarationVisitor::Pre(const parser::KindParam
&x
) {
4643 if (const auto *kind
{std::get_if
<
4644 parser::Scalar
<parser::Integer
<parser::Constant
<parser::Name
>>>>(
4646 const parser::Name
&name
{kind
->thing
.thing
.thing
};
4647 if (!FindSymbol(name
)) {
4648 Say(name
, "Parameter '%s' not found"_err_en_US
);
4654 bool DeclarationVisitor::Pre(const parser::DeclarationTypeSpec::Type
&) {
4655 CHECK(GetDeclTypeSpecCategory() == DeclTypeSpec::Category::TypeDerived
);
4659 void DeclarationVisitor::Post(const parser::DeclarationTypeSpec::Type
&type
) {
4660 const parser::Name
&derivedName
{std::get
<parser::Name
>(type
.derived
.t
)};
4661 if (const Symbol
* derivedSymbol
{derivedName
.symbol
}) {
4662 CheckForAbstractType(*derivedSymbol
); // C706
4666 bool DeclarationVisitor::Pre(const parser::DeclarationTypeSpec::Class
&) {
4667 SetDeclTypeSpecCategory(DeclTypeSpec::Category::ClassDerived
);
4671 void DeclarationVisitor::Post(
4672 const parser::DeclarationTypeSpec::Class
&parsedClass
) {
4673 const auto &typeName
{std::get
<parser::Name
>(parsedClass
.derived
.t
)};
4674 if (auto spec
{ResolveDerivedType(typeName
)};
4675 spec
&& !IsExtensibleType(&*spec
)) { // C705
4676 SayWithDecl(typeName
, *typeName
.symbol
,
4677 "Non-extensible derived type '%s' may not be used with CLASS"
4678 " keyword"_err_en_US
);
4682 void DeclarationVisitor::Post(const parser::DerivedTypeSpec
&x
) {
4683 const auto &typeName
{std::get
<parser::Name
>(x
.t
)};
4684 auto spec
{ResolveDerivedType(typeName
)};
4688 bool seenAnyName
{false};
4689 for (const auto &typeParamSpec
:
4690 std::get
<std::list
<parser::TypeParamSpec
>>(x
.t
)) {
4691 const auto &optKeyword
{
4692 std::get
<std::optional
<parser::Keyword
>>(typeParamSpec
.t
)};
4693 std::optional
<SourceName
> name
;
4696 name
= optKeyword
->v
.source
;
4697 } else if (seenAnyName
) {
4698 Say(typeName
.source
, "Type parameter value must have a name"_err_en_US
);
4701 const auto &value
{std::get
<parser::TypeParamValue
>(typeParamSpec
.t
)};
4702 // The expressions in a derived type specifier whose values define
4703 // non-defaulted type parameters are evaluated (folded) in the enclosing
4704 // scope. The KIND/LEN distinction is resolved later in
4705 // DerivedTypeSpec::CookParameters().
4706 ParamValue param
{GetParamValue(value
, common::TypeParamAttr::Kind
)};
4707 if (!param
.isExplicit() || param
.GetExplicit()) {
4708 spec
->AddRawParamValue(
4709 common::GetPtrFromOptional(optKeyword
), std::move(param
));
4712 // The DerivedTypeSpec *spec is used initially as a search key.
4713 // If it turns out to have the same name and actual parameter
4714 // value expressions as another DerivedTypeSpec in the current
4715 // scope does, then we'll use that extant spec; otherwise, when this
4716 // spec is distinct from all derived types previously instantiated
4717 // in the current scope, this spec will be moved into that collection.
4718 const auto &dtDetails
{spec
->typeSymbol().get
<DerivedTypeDetails
>()};
4719 auto category
{GetDeclTypeSpecCategory()};
4720 if (dtDetails
.isForwardReferenced()) {
4721 DeclTypeSpec
&type
{currScope().MakeDerivedType(category
, std::move(*spec
))};
4722 SetDeclTypeSpec(type
);
4725 // Normalize parameters to produce a better search key.
4726 spec
->CookParameters(GetFoldingContext());
4727 if (!spec
->MightBeParameterized()) {
4728 spec
->EvaluateParameters(context());
4730 if (const DeclTypeSpec
*
4731 extant
{currScope().FindInstantiatedDerivedType(*spec
, category
)}) {
4732 // This derived type and parameter expressions (if any) are already present
4734 SetDeclTypeSpec(*extant
);
4736 DeclTypeSpec
&type
{currScope().MakeDerivedType(category
, std::move(*spec
))};
4737 DerivedTypeSpec
&derived
{type
.derivedTypeSpec()};
4738 if (derived
.MightBeParameterized() &&
4739 currScope().IsParameterizedDerivedType()) {
4740 // Defer instantiation; use the derived type's definition's scope.
4741 derived
.set_scope(DEREF(spec
->typeSymbol().scope()));
4742 } else if (&currScope() == spec
->typeSymbol().scope()) {
4743 // Direct recursive use of a type in the definition of one of its
4744 // components: defer instantiation
4747 GetFoldingContext().messages().SetLocation(currStmtSource().value())};
4748 derived
.Instantiate(currScope());
4750 SetDeclTypeSpec(type
);
4752 // Capture the DerivedTypeSpec in the parse tree for use in building
4753 // structure constructor expressions.
4754 x
.derivedTypeSpec
= &GetDeclTypeSpec()->derivedTypeSpec();
4757 void DeclarationVisitor::Post(const parser::DeclarationTypeSpec::Record
&rec
) {
4758 const auto &typeName
{rec
.v
};
4759 if (auto spec
{ResolveDerivedType(typeName
)}) {
4760 spec
->CookParameters(GetFoldingContext());
4761 spec
->EvaluateParameters(context());
4762 if (const DeclTypeSpec
*
4763 extant
{currScope().FindInstantiatedDerivedType(
4764 *spec
, DeclTypeSpec::TypeDerived
)}) {
4765 SetDeclTypeSpec(*extant
);
4767 Say(typeName
.source
, "%s is not a known STRUCTURE"_err_en_US
,
4773 // The descendents of DerivedTypeDef in the parse tree are visited directly
4774 // in this Pre() routine so that recursive use of the derived type can be
4775 // supported in the components.
4776 bool DeclarationVisitor::Pre(const parser::DerivedTypeDef
&x
) {
4777 auto &stmt
{std::get
<parser::Statement
<parser::DerivedTypeStmt
>>(x
.t
)};
4779 Walk(std::get
<std::list
<parser::Statement
<parser::TypeParamDefStmt
>>>(x
.t
));
4780 auto &scope
{currScope()};
4781 CHECK(scope
.symbol());
4782 CHECK(scope
.symbol()->scope() == &scope
);
4783 auto &details
{scope
.symbol()->get
<DerivedTypeDetails
>()};
4784 details
.set_isForwardReferenced(false);
4785 std::set
<SourceName
> paramNames
;
4786 for (auto ¶mName
: std::get
<std::list
<parser::Name
>>(stmt
.statement
.t
)) {
4787 details
.add_paramName(paramName
.source
);
4788 auto *symbol
{FindInScope(scope
, paramName
)};
4791 "No definition found for type parameter '%s'"_err_en_US
); // C742
4792 // No symbol for a type param. Create one and mark it as containing an
4793 // error to improve subsequent semantic processing
4795 Symbol
*typeParam
{MakeTypeSymbol(
4796 paramName
, TypeParamDetails
{common::TypeParamAttr::Len
})};
4797 context().SetError(*typeParam
);
4799 } else if (!symbol
->has
<TypeParamDetails
>()) {
4800 Say2(paramName
, "'%s' is not defined as a type parameter"_err_en_US
,
4801 *symbol
, "Definition of '%s'"_en_US
); // C741
4803 if (!paramNames
.insert(paramName
.source
).second
) {
4805 "Duplicate type parameter name: '%s'"_err_en_US
); // C731
4808 for (const auto &[name
, symbol
] : currScope()) {
4809 if (symbol
->has
<TypeParamDetails
>() && !paramNames
.count(name
)) {
4810 SayDerivedType(name
,
4811 "'%s' is not a type parameter of this derived type"_err_en_US
,
4812 currScope()); // C741
4815 Walk(std::get
<std::list
<parser::Statement
<parser::PrivateOrSequence
>>>(x
.t
));
4816 const auto &componentDefs
{
4817 std::get
<std::list
<parser::Statement
<parser::ComponentDefStmt
>>>(x
.t
)};
4818 Walk(componentDefs
);
4819 if (derivedTypeInfo_
.sequence
) {
4820 details
.set_sequence(true);
4821 if (componentDefs
.empty()) { // C740
4823 "A sequence type must have at least one component"_err_en_US
);
4825 if (!details
.paramNames().empty()) { // C740
4827 "A sequence type may not have type parameters"_err_en_US
);
4829 if (derivedTypeInfo_
.extends
) { // C735
4831 "A sequence type may not have the EXTENDS attribute"_err_en_US
);
4834 Walk(std::get
<std::optional
<parser::TypeBoundProcedurePart
>>(x
.t
));
4835 Walk(std::get
<parser::Statement
<parser::EndTypeStmt
>>(x
.t
));
4836 derivedTypeInfo_
= {};
4841 bool DeclarationVisitor::Pre(const parser::DerivedTypeStmt
&) {
4842 return BeginAttrs();
4844 void DeclarationVisitor::Post(const parser::DerivedTypeStmt
&x
) {
4845 auto &name
{std::get
<parser::Name
>(x
.t
)};
4846 // Resolve the EXTENDS() clause before creating the derived
4847 // type's symbol to foil attempts to recursively extend a type.
4848 auto *extendsName
{derivedTypeInfo_
.extends
};
4849 std::optional
<DerivedTypeSpec
> extendsType
{
4850 ResolveExtendsType(name
, extendsName
)};
4851 auto &symbol
{MakeSymbol(name
, GetAttrs(), DerivedTypeDetails
{})};
4852 symbol
.ReplaceName(name
.source
);
4853 derivedTypeInfo_
.type
= &symbol
;
4854 PushScope(Scope::Kind::DerivedType
, &symbol
);
4856 // Declare the "parent component"; private if the type is.
4857 // Any symbol stored in the EXTENDS() clause is temporarily
4858 // hidden so that a new symbol can be created for the parent
4859 // component without producing spurious errors about already
4861 const Symbol
&extendsSymbol
{extendsType
->typeSymbol()};
4862 auto restorer
{common::ScopedSet(extendsName
->symbol
, nullptr)};
4863 if (OkToAddComponent(*extendsName
, &extendsSymbol
)) {
4864 auto &comp
{DeclareEntity
<ObjectEntityDetails
>(*extendsName
, Attrs
{})};
4866 Attr::PRIVATE
, extendsSymbol
.attrs().test(Attr::PRIVATE
));
4867 comp
.implicitAttrs().set(
4868 Attr::PRIVATE
, extendsSymbol
.implicitAttrs().test(Attr::PRIVATE
));
4869 comp
.set(Symbol::Flag::ParentComp
);
4870 DeclTypeSpec
&type
{currScope().MakeDerivedType(
4871 DeclTypeSpec::TypeDerived
, std::move(*extendsType
))};
4872 type
.derivedTypeSpec().set_scope(*extendsSymbol
.scope());
4874 DerivedTypeDetails
&details
{symbol
.get
<DerivedTypeDetails
>()};
4875 details
.add_component(comp
);
4881 void DeclarationVisitor::Post(const parser::TypeParamDefStmt
&x
) {
4882 auto *type
{GetDeclTypeSpec()};
4883 auto attr
{std::get
<common::TypeParamAttr
>(x
.t
)};
4884 for (auto &decl
: std::get
<std::list
<parser::TypeParamDecl
>>(x
.t
)) {
4885 auto &name
{std::get
<parser::Name
>(decl
.t
)};
4886 if (Symbol
* symbol
{MakeTypeSymbol(name
, TypeParamDetails
{attr
})}) {
4887 SetType(name
, *type
);
4889 std::get
<std::optional
<parser::ScalarIntConstantExpr
>>(decl
.t
)}) {
4890 if (auto maybeExpr
{EvaluateNonPointerInitializer(
4891 *symbol
, *init
, init
->thing
.thing
.thing
.value().source
)}) {
4892 if (auto *intExpr
{std::get_if
<SomeIntExpr
>(&maybeExpr
->u
)}) {
4893 symbol
->get
<TypeParamDetails
>().set_init(std::move(*intExpr
));
4901 bool DeclarationVisitor::Pre(const parser::TypeAttrSpec::Extends
&x
) {
4902 if (derivedTypeInfo_
.extends
) {
4903 Say(currStmtSource().value(),
4904 "Attribute 'EXTENDS' cannot be used more than once"_err_en_US
);
4906 derivedTypeInfo_
.extends
= &x
.v
;
4911 bool DeclarationVisitor::Pre(const parser::PrivateStmt
&) {
4912 if (!currScope().parent().IsModule()) {
4913 Say("PRIVATE is only allowed in a derived type that is"
4914 " in a module"_err_en_US
); // C766
4915 } else if (derivedTypeInfo_
.sawContains
) {
4916 derivedTypeInfo_
.privateBindings
= true;
4917 } else if (!derivedTypeInfo_
.privateComps
) {
4918 derivedTypeInfo_
.privateComps
= true;
4920 Say("PRIVATE may not appear more than once in"
4921 " derived type components"_warn_en_US
); // C738
4925 bool DeclarationVisitor::Pre(const parser::SequenceStmt
&) {
4926 if (derivedTypeInfo_
.sequence
) {
4927 Say("SEQUENCE may not appear more than once in"
4928 " derived type components"_warn_en_US
); // C738
4930 derivedTypeInfo_
.sequence
= true;
4933 void DeclarationVisitor::Post(const parser::ComponentDecl
&x
) {
4934 const auto &name
{std::get
<parser::Name
>(x
.t
)};
4935 auto attrs
{GetAttrs()};
4936 if (derivedTypeInfo_
.privateComps
&&
4937 !attrs
.HasAny({Attr::PUBLIC
, Attr::PRIVATE
})) {
4938 attrs
.set(Attr::PRIVATE
);
4940 if (const auto *declType
{GetDeclTypeSpec()}) {
4941 if (const auto *derived
{declType
->AsDerived()}) {
4942 if (!attrs
.HasAny({Attr::POINTER
, Attr::ALLOCATABLE
})) {
4943 if (derivedTypeInfo_
.type
== &derived
->typeSymbol()) { // C744
4944 Say("Recursive use of the derived type requires "
4945 "POINTER or ALLOCATABLE"_err_en_US
);
4948 // TODO: This would be more appropriate in CheckDerivedType()
4949 if (auto it
{FindCoarrayUltimateComponent(*derived
)}) { // C748
4950 std::string ultimateName
{it
.BuildResultDesignatorName()};
4951 // Strip off the leading "%"
4952 if (ultimateName
.length() > 1) {
4953 ultimateName
.erase(0, 1);
4954 if (attrs
.HasAny({Attr::POINTER
, Attr::ALLOCATABLE
})) {
4955 evaluate::AttachDeclaration(
4957 "A component with a POINTER or ALLOCATABLE attribute may "
4959 "be of a type with a coarray ultimate component (named "
4962 derived
->typeSymbol());
4964 if (!arraySpec().empty() || !coarraySpec().empty()) {
4965 evaluate::AttachDeclaration(
4967 "An array or coarray component may not be of a type with a "
4968 "coarray ultimate component (named '%s')"_err_en_US
,
4970 derived
->typeSymbol());
4976 if (OkToAddComponent(name
)) {
4977 auto &symbol
{DeclareObjectEntity(name
, attrs
)};
4978 if (symbol
.has
<ObjectEntityDetails
>()) {
4979 if (auto &init
{std::get
<std::optional
<parser::Initialization
>>(x
.t
)}) {
4980 Initialization(name
, *init
, true);
4983 currScope().symbol()->get
<DerivedTypeDetails
>().add_component(symbol
);
4988 void DeclarationVisitor::Post(const parser::FillDecl
&x
) {
4989 // Replace "%FILL" with a distinct generated name
4990 const auto &name
{std::get
<parser::Name
>(x
.t
)};
4991 const_cast<SourceName
&>(name
.source
) = context().GetTempName(currScope());
4992 if (OkToAddComponent(name
)) {
4993 auto &symbol
{DeclareObjectEntity(name
, GetAttrs())};
4994 currScope().symbol()->get
<DerivedTypeDetails
>().add_component(symbol
);
4998 bool DeclarationVisitor::Pre(const parser::ProcedureDeclarationStmt
&x
) {
4999 CHECK(!interfaceName_
);
5000 const auto &procAttrSpec
{std::get
<std::list
<parser::ProcAttrSpec
>>(x
.t
)};
5001 for (const parser::ProcAttrSpec
&procAttr
: procAttrSpec
) {
5002 if (auto *bindC
{std::get_if
<parser::LanguageBindingSpec
>(&procAttr
.u
)}) {
5003 if (bindC
->v
.has_value()) {
5004 hasBindCName_
= true;
5011 void DeclarationVisitor::Post(const parser::ProcedureDeclarationStmt
&) {
5012 interfaceName_
= nullptr;
5013 hasBindCName_
= false;
5016 bool DeclarationVisitor::Pre(const parser::DataComponentDefStmt
&x
) {
5017 // Overrides parse tree traversal so as to handle attributes first,
5018 // so POINTER & ALLOCATABLE enable forward references to derived types.
5019 Walk(std::get
<std::list
<parser::ComponentAttrSpec
>>(x
.t
));
5020 set_allowForwardReferenceToDerivedType(
5021 GetAttrs().HasAny({Attr::POINTER
, Attr::ALLOCATABLE
}));
5022 Walk(std::get
<parser::DeclarationTypeSpec
>(x
.t
));
5023 set_allowForwardReferenceToDerivedType(false);
5024 if (derivedTypeInfo_
.sequence
) { // C740
5025 if (const auto *declType
{GetDeclTypeSpec()}) {
5026 if (!declType
->AsIntrinsic() && !declType
->IsSequenceType() &&
5028 if (GetAttrs().test(Attr::POINTER
) &&
5029 context().IsEnabled(common::LanguageFeature::PointerInSeqType
)) {
5030 if (context().ShouldWarn(common::LanguageFeature::PointerInSeqType
)) {
5031 Say("A sequence type data component that is a pointer to a non-sequence type is not standard"_port_en_US
);
5034 Say("A sequence type data component must either be of an intrinsic type or a derived sequence type"_err_en_US
);
5039 Walk(std::get
<std::list
<parser::ComponentOrFill
>>(x
.t
));
5042 bool DeclarationVisitor::Pre(const parser::ProcComponentDefStmt
&) {
5043 CHECK(!interfaceName_
);
5046 void DeclarationVisitor::Post(const parser::ProcComponentDefStmt
&) {
5047 interfaceName_
= nullptr;
5049 bool DeclarationVisitor::Pre(const parser::ProcPointerInit
&x
) {
5050 if (auto *name
{std::get_if
<parser::Name
>(&x
.u
)}) {
5051 return !NameIsKnownOrIntrinsic(*name
) && !CheckUseError(*name
);
5053 const auto &null
{DEREF(std::get_if
<parser::NullInit
>(&x
.u
))};
5055 if (auto nullInit
{EvaluateExpr(null
)}) {
5056 if (!evaluate::IsNullPointer(*nullInit
)) {
5057 Say(null
.v
.value().source
,
5058 "Procedure pointer initializer must be a name or intrinsic NULL()"_err_en_US
);
5064 void DeclarationVisitor::Post(const parser::ProcInterface
&x
) {
5065 if (auto *name
{std::get_if
<parser::Name
>(&x
.u
)}) {
5066 interfaceName_
= name
;
5067 NoteInterfaceName(*name
);
5070 void DeclarationVisitor::Post(const parser::ProcDecl
&x
) {
5071 const auto &name
{std::get
<parser::Name
>(x
.t
)};
5072 const Symbol
*procInterface
{nullptr};
5073 if (interfaceName_
) {
5074 procInterface
= interfaceName_
->symbol
;
5076 auto attrs
{HandleSaveName(name
.source
, GetAttrs())};
5077 DerivedTypeDetails
*dtDetails
{nullptr};
5078 if (Symbol
* symbol
{currScope().symbol()}) {
5079 dtDetails
= symbol
->detailsIf
<DerivedTypeDetails
>();
5082 attrs
.set(Attr::EXTERNAL
);
5084 Symbol
&symbol
{DeclareProcEntity(name
, attrs
, procInterface
)};
5085 symbol
.ReplaceName(name
.source
);
5087 dtDetails
->add_component(symbol
);
5091 bool DeclarationVisitor::Pre(const parser::TypeBoundProcedurePart
&) {
5092 derivedTypeInfo_
.sawContains
= true;
5096 // Resolve binding names from type-bound generics, saved in genericBindings_.
5097 void DeclarationVisitor::Post(const parser::TypeBoundProcedurePart
&) {
5098 // track specifics seen for the current generic to detect duplicates:
5099 const Symbol
*currGeneric
{nullptr};
5100 std::set
<SourceName
> specifics
;
5101 for (const auto &[generic
, bindingName
] : genericBindings_
) {
5102 if (generic
!= currGeneric
) {
5103 currGeneric
= generic
;
5106 auto [it
, inserted
]{specifics
.insert(bindingName
->source
)};
5108 Say(*bindingName
, // C773
5109 "Binding name '%s' was already specified for generic '%s'"_err_en_US
,
5110 bindingName
->source
, generic
->name())
5111 .Attach(*it
, "Previous specification of '%s'"_en_US
, *it
);
5114 auto *symbol
{FindInTypeOrParents(*bindingName
)};
5116 Say(*bindingName
, // C772
5117 "Binding name '%s' not found in this derived type"_err_en_US
);
5118 } else if (!symbol
->has
<ProcBindingDetails
>()) {
5119 SayWithDecl(*bindingName
, *symbol
, // C772
5120 "'%s' is not the name of a specific binding of this type"_err_en_US
);
5122 generic
->get
<GenericDetails
>().AddSpecificProc(
5123 *symbol
, bindingName
->source
);
5126 genericBindings_
.clear();
5129 void DeclarationVisitor::Post(const parser::ContainsStmt
&) {
5130 if (derivedTypeInfo_
.sequence
) {
5131 Say("A sequence type may not have a CONTAINS statement"_err_en_US
); // C740
5135 void DeclarationVisitor::Post(
5136 const parser::TypeBoundProcedureStmt::WithoutInterface
&x
) {
5137 if (GetAttrs().test(Attr::DEFERRED
)) { // C783
5138 Say("DEFERRED is only allowed when an interface-name is provided"_err_en_US
);
5140 for (auto &declaration
: x
.declarations
) {
5141 auto &bindingName
{std::get
<parser::Name
>(declaration
.t
)};
5142 auto &optName
{std::get
<std::optional
<parser::Name
>>(declaration
.t
)};
5143 const parser::Name
&procedureName
{optName
? *optName
: bindingName
};
5144 Symbol
*procedure
{FindSymbol(procedureName
)};
5146 procedure
= NoteInterfaceName(procedureName
);
5149 const Symbol
&bindTo
{BypassGeneric(*procedure
)};
5150 if (auto *s
{MakeTypeSymbol(bindingName
, ProcBindingDetails
{bindTo
})}) {
5152 if (GetAttrs().test(Attr::DEFERRED
)) {
5153 context().SetError(*s
);
5160 void DeclarationVisitor::CheckBindings(
5161 const parser::TypeBoundProcedureStmt::WithoutInterface
&tbps
) {
5162 CHECK(currScope().IsDerivedType());
5163 for (auto &declaration
: tbps
.declarations
) {
5164 auto &bindingName
{std::get
<parser::Name
>(declaration
.t
)};
5165 if (Symbol
* binding
{FindInScope(bindingName
)}) {
5166 if (auto *details
{binding
->detailsIf
<ProcBindingDetails
>()}) {
5167 const Symbol
&ultimate
{details
->symbol().GetUltimate()};
5168 const Symbol
&procedure
{BypassGeneric(ultimate
)};
5169 if (&procedure
!= &ultimate
) {
5170 details
->ReplaceSymbol(procedure
);
5172 if (!CanBeTypeBoundProc(procedure
)) {
5173 if (details
->symbol().name() != binding
->name()) {
5174 Say(binding
->name(),
5175 "The binding of '%s' ('%s') must be either an accessible "
5176 "module procedure or an external procedure with "
5177 "an explicit interface"_err_en_US
,
5178 binding
->name(), details
->symbol().name());
5180 Say(binding
->name(),
5181 "'%s' must be either an accessible module procedure "
5182 "or an external procedure with an explicit interface"_err_en_US
,
5185 context().SetError(*binding
);
5192 void DeclarationVisitor::Post(
5193 const parser::TypeBoundProcedureStmt::WithInterface
&x
) {
5194 if (!GetAttrs().test(Attr::DEFERRED
)) { // C783
5195 Say("DEFERRED is required when an interface-name is provided"_err_en_US
);
5197 if (Symbol
* interface
{NoteInterfaceName(x
.interfaceName
)}) {
5198 for (auto &bindingName
: x
.bindingNames
) {
5200 MakeTypeSymbol(bindingName
, ProcBindingDetails
{*interface
})}) {
5202 if (!GetAttrs().test(Attr::DEFERRED
)) {
5203 context().SetError(*s
);
5210 void DeclarationVisitor::Post(const parser::FinalProcedureStmt
&x
) {
5211 if (currScope().IsDerivedType() && currScope().symbol()) {
5212 if (auto *details
{currScope().symbol()->detailsIf
<DerivedTypeDetails
>()}) {
5213 for (const auto &subrName
: x
.v
) {
5214 if (const auto *name
{ResolveName(subrName
)}) {
5216 details
->finals().emplace(name
->source
, DEREF(name
->symbol
))};
5217 if (!pair
.second
) { // C787
5219 "FINAL subroutine '%s' already appeared in this derived type"_err_en_US
,
5221 .Attach(pair
.first
->first
,
5222 "earlier appearance of this FINAL subroutine"_en_US
);
5230 bool DeclarationVisitor::Pre(const parser::TypeBoundGenericStmt
&x
) {
5231 const auto &accessSpec
{std::get
<std::optional
<parser::AccessSpec
>>(x
.t
)};
5232 const auto &genericSpec
{std::get
<Indirection
<parser::GenericSpec
>>(x
.t
)};
5233 const auto &bindingNames
{std::get
<std::list
<parser::Name
>>(x
.t
)};
5234 GenericSpecInfo info
{genericSpec
.value()};
5235 SourceName symbolName
{info
.symbolName()};
5236 bool isPrivate
{accessSpec
? accessSpec
->v
== parser::AccessSpec::Kind::Private
5237 : derivedTypeInfo_
.privateBindings
};
5238 auto *genericSymbol
{FindInScope(symbolName
)};
5239 if (genericSymbol
) {
5240 if (!genericSymbol
->has
<GenericDetails
>()) {
5241 genericSymbol
= nullptr; // MakeTypeSymbol will report the error below
5244 // look in ancestor types for a generic of the same name
5245 for (const auto &name
: GetAllNames(context(), symbolName
)) {
5246 if (Symbol
* inherited
{currScope().FindComponent(SourceName
{name
})}) {
5247 if (inherited
->has
<GenericDetails
>()) {
5248 CheckAccessibility(symbolName
, isPrivate
, *inherited
); // C771
5251 "Type bound generic procedure '%s' may not have the same name as a non-generic symbol inherited from an ancestor type"_err_en_US
)
5252 .Attach(inherited
->name(), "Inherited symbol"_en_US
);
5258 if (genericSymbol
) {
5259 CheckAccessibility(symbolName
, isPrivate
, *genericSymbol
); // C771
5261 genericSymbol
= MakeTypeSymbol(symbolName
, GenericDetails
{});
5262 if (!genericSymbol
) {
5266 SetExplicitAttr(*genericSymbol
, Attr::PRIVATE
);
5269 for (const parser::Name
&bindingName
: bindingNames
) {
5270 genericBindings_
.emplace(genericSymbol
, &bindingName
);
5272 info
.Resolve(genericSymbol
);
5276 // DEC STRUCTUREs are handled thus to allow for nested definitions.
5277 bool DeclarationVisitor::Pre(const parser::StructureDef
&def
) {
5278 const auto &structureStatement
{
5279 std::get
<parser::Statement
<parser::StructureStmt
>>(def
.t
)};
5280 auto saveDerivedTypeInfo
{derivedTypeInfo_
};
5281 derivedTypeInfo_
= {};
5282 derivedTypeInfo_
.isStructure
= true;
5283 derivedTypeInfo_
.sequence
= true;
5284 Scope
*previousStructure
{nullptr};
5285 if (saveDerivedTypeInfo
.isStructure
) {
5286 previousStructure
= &currScope();
5289 const parser::StructureStmt
&structStmt
{structureStatement
.statement
};
5290 const auto &name
{std::get
<std::optional
<parser::Name
>>(structStmt
.t
)};
5292 // Construct a distinct generated name for an anonymous structure
5293 auto &mutableName
{const_cast<std::optional
<parser::Name
> &>(name
)};
5294 mutableName
.emplace(
5295 parser::Name
{context().GetTempName(currScope()), nullptr});
5297 auto &symbol
{MakeSymbol(*name
, DerivedTypeDetails
{})};
5298 symbol
.ReplaceName(name
->source
);
5299 symbol
.get
<DerivedTypeDetails
>().set_sequence(true);
5300 symbol
.get
<DerivedTypeDetails
>().set_isDECStructure(true);
5301 derivedTypeInfo_
.type
= &symbol
;
5302 PushScope(Scope::Kind::DerivedType
, &symbol
);
5303 const auto &fields
{std::get
<std::list
<parser::StructureField
>>(def
.t
)};
5306 // Complete the definition
5307 DerivedTypeSpec derivedTypeSpec
{symbol
.name(), symbol
};
5308 derivedTypeSpec
.set_scope(DEREF(symbol
.scope()));
5309 derivedTypeSpec
.CookParameters(GetFoldingContext());
5310 derivedTypeSpec
.EvaluateParameters(context());
5311 DeclTypeSpec
&type
{currScope().MakeDerivedType(
5312 DeclTypeSpec::TypeDerived
, std::move(derivedTypeSpec
))};
5313 type
.derivedTypeSpec().Instantiate(currScope());
5314 // Restore previous structure definition context, if any
5315 derivedTypeInfo_
= saveDerivedTypeInfo
;
5316 if (previousStructure
) {
5317 PushScope(*previousStructure
);
5319 // Handle any entity declarations on the STRUCTURE statement
5320 const auto &decls
{std::get
<std::list
<parser::EntityDecl
>>(structStmt
.t
)};
5321 if (!decls
.empty()) {
5323 SetDeclTypeSpec(type
);
5330 bool DeclarationVisitor::Pre(const parser::Union::UnionStmt
&) {
5331 Say("support for UNION"_todo_en_US
); // TODO
5335 bool DeclarationVisitor::Pre(const parser::StructureField
&x
) {
5336 if (std::holds_alternative
<parser::Statement
<parser::DataComponentDefStmt
>>(
5343 void DeclarationVisitor::Post(const parser::StructureField
&x
) {
5344 if (std::holds_alternative
<parser::Statement
<parser::DataComponentDefStmt
>>(
5350 bool DeclarationVisitor::Pre(const parser::AllocateStmt
&) {
5351 BeginDeclTypeSpec();
5354 void DeclarationVisitor::Post(const parser::AllocateStmt
&) {
5358 bool DeclarationVisitor::Pre(const parser::StructureConstructor
&x
) {
5359 auto &parsedType
{std::get
<parser::DerivedTypeSpec
>(x
.t
)};
5360 const DeclTypeSpec
*type
{ProcessTypeSpec(parsedType
)};
5364 const DerivedTypeSpec
*spec
{type
->AsDerived()};
5365 const Scope
*typeScope
{spec
? spec
->scope() : nullptr};
5370 // N.B C7102 is implicitly enforced by having inaccessible types not
5371 // being found in resolution.
5372 // More constraints are enforced in expression.cpp so that they
5373 // can apply to structure constructors that have been converted
5374 // from misparsed function references.
5375 for (const auto &component
:
5376 std::get
<std::list
<parser::ComponentSpec
>>(x
.t
)) {
5377 // Visit the component spec expression, but not the keyword, since
5378 // we need to resolve its symbol in the scope of the derived type.
5379 Walk(std::get
<parser::ComponentDataSource
>(component
.t
));
5380 if (const auto &kw
{std::get
<std::optional
<parser::Keyword
>>(component
.t
)}) {
5381 FindInTypeOrParents(*typeScope
, kw
->v
);
5387 bool DeclarationVisitor::Pre(const parser::BasedPointerStmt
&x
) {
5388 for (const parser::BasedPointer
&bp
: x
.v
) {
5389 const parser::ObjectName
&pointerName
{std::get
<0>(bp
.t
)};
5390 const parser::ObjectName
&pointeeName
{std::get
<1>(bp
.t
)};
5391 auto *pointer
{FindSymbol(pointerName
)};
5393 pointer
= &MakeSymbol(pointerName
, ObjectEntityDetails
{});
5394 } else if (!ConvertToObjectEntity(*pointer
) || IsNamedConstant(*pointer
)) {
5395 SayWithDecl(pointerName
, *pointer
, "'%s' is not a variable"_err_en_US
);
5396 } else if (pointer
->Rank() > 0) {
5397 SayWithDecl(pointerName
, *pointer
,
5398 "Cray pointer '%s' must be a scalar"_err_en_US
);
5399 } else if (pointer
->test(Symbol::Flag::CrayPointee
)) {
5401 "'%s' cannot be a Cray pointer as it is already a Cray pointee"_err_en_US
);
5403 pointer
->set(Symbol::Flag::CrayPointer
);
5404 const DeclTypeSpec
&pointerType
{MakeNumericType(TypeCategory::Integer
,
5405 context().defaultKinds().subscriptIntegerKind())};
5406 const auto *type
{pointer
->GetType()};
5408 pointer
->SetType(pointerType
);
5409 } else if (*type
!= pointerType
) {
5410 Say(pointerName
.source
, "Cray pointer '%s' must have type %s"_err_en_US
,
5411 pointerName
.source
, pointerType
.AsFortran());
5413 if (ResolveName(pointeeName
)) {
5414 Symbol
&pointee
{*pointeeName
.symbol
};
5415 if (pointee
.has
<UseDetails
>()) {
5417 "'%s' cannot be a Cray pointee as it is use-associated"_err_en_US
);
5419 } else if (!ConvertToObjectEntity(pointee
) || IsNamedConstant(pointee
)) {
5420 Say(pointeeName
, "'%s' is not a variable"_err_en_US
);
5422 } else if (pointee
.test(Symbol::Flag::CrayPointer
)) {
5424 "'%s' cannot be a Cray pointee as it is already a Cray pointer"_err_en_US
);
5425 } else if (pointee
.test(Symbol::Flag::CrayPointee
)) {
5427 "'%s' was already declared as a Cray pointee"_err_en_US
);
5429 pointee
.set(Symbol::Flag::CrayPointee
);
5431 if (const auto *pointeeType
{pointee
.GetType()}) {
5432 if (const auto *derived
{pointeeType
->AsDerived()}) {
5433 if (!derived
->typeSymbol().get
<DerivedTypeDetails
>().sequence()) {
5435 "Type of Cray pointee '%s' is a non-sequence derived type"_err_en_US
);
5439 // process the pointee array-spec, if present
5441 Walk(std::get
<std::optional
<parser::ArraySpec
>>(bp
.t
));
5442 const auto &spec
{arraySpec()};
5443 if (!spec
.empty()) {
5444 auto &details
{pointee
.get
<ObjectEntityDetails
>()};
5445 if (details
.shape().empty()) {
5446 details
.set_shape(spec
);
5448 SayWithDecl(pointeeName
, pointee
,
5449 "Array spec was already declared for '%s'"_err_en_US
);
5453 currScope().add_crayPointer(pointeeName
.source
, *pointer
);
5459 bool DeclarationVisitor::Pre(const parser::NamelistStmt::Group
&x
) {
5460 if (!CheckNotInBlock("NAMELIST")) { // C1107
5463 const auto &groupName
{std::get
<parser::Name
>(x
.t
)};
5464 auto *groupSymbol
{FindInScope(groupName
)};
5465 if (!groupSymbol
|| !groupSymbol
->has
<NamelistDetails
>()) {
5466 groupSymbol
= &MakeSymbol(groupName
, NamelistDetails
{});
5467 groupSymbol
->ReplaceName(groupName
.source
);
5469 // Name resolution of group items is deferred to FinishNamelists()
5470 // so that host association is handled correctly.
5471 GetDeferredDeclarationState(true)->namelistGroups
.emplace_back(&x
);
5475 void DeclarationVisitor::FinishNamelists() {
5476 if (auto *deferred
{GetDeferredDeclarationState()}) {
5477 for (const parser::NamelistStmt::Group
*group
: deferred
->namelistGroups
) {
5478 if (auto *groupSymbol
{FindInScope(std::get
<parser::Name
>(group
->t
))}) {
5479 if (auto *details
{groupSymbol
->detailsIf
<NamelistDetails
>()}) {
5480 for (const auto &name
: std::get
<std::list
<parser::Name
>>(group
->t
)) {
5481 auto *symbol
{FindSymbol(name
)};
5483 symbol
= &MakeSymbol(name
, ObjectEntityDetails
{});
5484 ApplyImplicitRules(*symbol
);
5485 } else if (!ConvertToObjectEntity(*symbol
)) {
5486 SayWithDecl(name
, *symbol
, "'%s' is not a variable"_err_en_US
);
5488 symbol
->GetUltimate().set(Symbol::Flag::InNamelist
);
5489 details
->add_object(*symbol
);
5494 deferred
->namelistGroups
.clear();
5498 bool DeclarationVisitor::Pre(const parser::IoControlSpec
&x
) {
5499 if (const auto *name
{std::get_if
<parser::Name
>(&x
.u
)}) {
5500 auto *symbol
{FindSymbol(*name
)};
5502 Say(*name
, "Namelist group '%s' not found"_err_en_US
);
5503 } else if (!symbol
->GetUltimate().has
<NamelistDetails
>()) {
5505 *name
, *symbol
, "'%s' is not the name of a namelist group"_err_en_US
);
5511 bool DeclarationVisitor::Pre(const parser::CommonStmt::Block
&x
) {
5512 CheckNotInBlock("COMMON"); // C1107
5516 bool DeclarationVisitor::Pre(const parser::CommonBlockObject
&) {
5521 void DeclarationVisitor::Post(const parser::CommonBlockObject
&x
) {
5522 const auto &name
{std::get
<parser::Name
>(x
.t
)};
5523 DeclareObjectEntity(name
);
5524 auto pair
{specPartState_
.commonBlockObjects
.insert(name
.source
)};
5526 const SourceName
&prev
{*pair
.first
};
5527 Say2(name
.source
, "'%s' is already in a COMMON block"_err_en_US
, prev
,
5528 "Previous occurrence of '%s' in a COMMON block"_en_US
);
5532 bool DeclarationVisitor::Pre(const parser::EquivalenceStmt
&x
) {
5533 // save equivalence sets to be processed after specification part
5534 if (CheckNotInBlock("EQUIVALENCE")) { // C1107
5535 for (const std::list
<parser::EquivalenceObject
> &set
: x
.v
) {
5536 specPartState_
.equivalenceSets
.push_back(&set
);
5539 return false; // don't implicitly declare names yet
5542 void DeclarationVisitor::CheckEquivalenceSets() {
5543 EquivalenceSets equivSets
{context()};
5544 inEquivalenceStmt_
= true;
5545 for (const auto *set
: specPartState_
.equivalenceSets
) {
5546 const auto &source
{set
->front().v
.value().source
};
5547 if (set
->size() <= 1) { // R871
5548 Say(source
, "Equivalence set must have more than one object"_err_en_US
);
5550 for (const parser::EquivalenceObject
&object
: *set
) {
5551 const auto &designator
{object
.v
.value()};
5552 // The designator was not resolved when it was encountered so do it now.
5553 // AnalyzeExpr causes array sections to be changed to substrings as needed
5555 if (AnalyzeExpr(context(), designator
)) {
5556 equivSets
.AddToSet(designator
);
5559 equivSets
.FinishSet(source
);
5561 inEquivalenceStmt_
= false;
5562 for (auto &set
: equivSets
.sets()) {
5564 currScope().add_equivalenceSet(std::move(set
));
5567 specPartState_
.equivalenceSets
.clear();
5570 bool DeclarationVisitor::Pre(const parser::SaveStmt
&x
) {
5572 specPartState_
.saveInfo
.saveAll
= currStmtSource();
5573 currScope().set_hasSAVE();
5575 for (const parser::SavedEntity
&y
: x
.v
) {
5576 auto kind
{std::get
<parser::SavedEntity::Kind
>(y
.t
)};
5577 const auto &name
{std::get
<parser::Name
>(y
.t
)};
5578 if (kind
== parser::SavedEntity::Kind::Common
) {
5579 MakeCommonBlockSymbol(name
);
5580 AddSaveName(specPartState_
.saveInfo
.commons
, name
.source
);
5582 HandleAttributeStmt(Attr::SAVE
, name
);
5589 void DeclarationVisitor::CheckSaveStmts() {
5590 for (const SourceName
&name
: specPartState_
.saveInfo
.entities
) {
5591 auto *symbol
{FindInScope(name
)};
5593 // error was reported
5594 } else if (specPartState_
.saveInfo
.saveAll
) {
5595 // C889 - note that pgi, ifort, xlf do not enforce this constraint
5597 "Explicit SAVE of '%s' is redundant due to global SAVE statement"_warn_en_US
,
5598 *specPartState_
.saveInfo
.saveAll
, "Global SAVE statement"_en_US
);
5599 } else if (auto msg
{CheckSaveAttr(*symbol
)}) {
5600 Say(name
, std::move(*msg
));
5601 context().SetError(*symbol
);
5603 SetSaveAttr(*symbol
);
5606 for (const SourceName
&name
: specPartState_
.saveInfo
.commons
) {
5607 if (auto *symbol
{currScope().FindCommonBlock(name
)}) {
5608 auto &objects
{symbol
->get
<CommonBlockDetails
>().objects()};
5609 if (objects
.empty()) {
5610 if (currScope().kind() != Scope::Kind::BlockConstruct
) {
5612 "'%s' appears as a COMMON block in a SAVE statement but not in"
5613 " a COMMON statement"_err_en_US
);
5616 "SAVE statement in BLOCK construct may not contain a"
5617 " common block name '%s'"_err_en_US
);
5620 for (auto &object
: symbol
->get
<CommonBlockDetails
>().objects()) {
5621 SetSaveAttr(*object
);
5626 if (specPartState_
.saveInfo
.saveAll
) {
5627 // Apply SAVE attribute to applicable symbols
5628 for (auto pair
: currScope()) {
5629 auto &symbol
{*pair
.second
};
5630 if (!CheckSaveAttr(symbol
)) {
5631 SetSaveAttr(symbol
);
5635 specPartState_
.saveInfo
= {};
5638 // If SAVE attribute can't be set on symbol, return error message.
5639 std::optional
<MessageFixedText
> DeclarationVisitor::CheckSaveAttr(
5640 const Symbol
&symbol
) {
5641 if (IsDummy(symbol
)) {
5642 return "SAVE attribute may not be applied to dummy argument '%s'"_err_en_US
;
5643 } else if (symbol
.IsFuncResult()) {
5644 return "SAVE attribute may not be applied to function result '%s'"_err_en_US
;
5645 } else if (symbol
.has
<ProcEntityDetails
>() &&
5646 !symbol
.attrs().test(Attr::POINTER
)) {
5647 return "Procedure '%s' with SAVE attribute must also have POINTER attribute"_err_en_US
;
5648 } else if (IsAutomatic(symbol
)) {
5649 return "SAVE attribute may not be applied to automatic data object '%s'"_err_en_US
;
5651 return std::nullopt
;
5655 // Record SAVEd names in specPartState_.saveInfo.entities.
5656 Attrs
DeclarationVisitor::HandleSaveName(const SourceName
&name
, Attrs attrs
) {
5657 if (attrs
.test(Attr::SAVE
)) {
5658 AddSaveName(specPartState_
.saveInfo
.entities
, name
);
5663 // Record a name in a set of those to be saved.
5664 void DeclarationVisitor::AddSaveName(
5665 std::set
<SourceName
> &set
, const SourceName
&name
) {
5666 auto pair
{set
.insert(name
)};
5668 Say2(name
, "SAVE attribute was already specified on '%s'"_warn_en_US
,
5669 *pair
.first
, "Previous specification of SAVE attribute"_en_US
);
5673 // Set the SAVE attribute on symbol unless it is implicitly saved anyway.
5674 void DeclarationVisitor::SetSaveAttr(Symbol
&symbol
) {
5675 if (!IsSaved(symbol
)) {
5676 SetImplicitAttr(symbol
, Attr::SAVE
);
5680 // Check types of common block objects, now that they are known.
5681 void DeclarationVisitor::CheckCommonBlocks() {
5682 // check for empty common blocks
5683 for (const auto &pair
: currScope().commonBlocks()) {
5684 const auto &symbol
{*pair
.second
};
5685 if (symbol
.get
<CommonBlockDetails
>().objects().empty() &&
5686 symbol
.attrs().test(Attr::BIND_C
)) {
5688 "'%s' appears as a COMMON block in a BIND statement but not in"
5689 " a COMMON statement"_err_en_US
);
5692 // check objects in common blocks
5693 for (const auto &name
: specPartState_
.commonBlockObjects
) {
5694 const auto *symbol
{currScope().FindSymbol(name
)};
5698 const auto &attrs
{symbol
->attrs()};
5699 if (attrs
.test(Attr::ALLOCATABLE
)) {
5701 "ALLOCATABLE object '%s' may not appear in a COMMON block"_err_en_US
);
5702 } else if (attrs
.test(Attr::BIND_C
)) {
5704 "Variable '%s' with BIND attribute may not appear in a COMMON block"_err_en_US
);
5705 } else if (IsNamedConstant(*symbol
)) {
5707 "A named constant '%s' may not appear in a COMMON block"_err_en_US
);
5708 } else if (IsDummy(*symbol
)) {
5710 "Dummy argument '%s' may not appear in a COMMON block"_err_en_US
);
5711 } else if (symbol
->IsFuncResult()) {
5713 "Function result '%s' may not appear in a COMMON block"_err_en_US
);
5714 } else if (const DeclTypeSpec
* type
{symbol
->GetType()}) {
5715 if (type
->category() == DeclTypeSpec::ClassStar
) {
5717 "Unlimited polymorphic pointer '%s' may not appear in a COMMON block"_err_en_US
);
5718 } else if (const auto *derived
{type
->AsDerived()}) {
5719 auto &typeSymbol
{derived
->typeSymbol()};
5720 if (!typeSymbol
.attrs().test(Attr::BIND_C
) &&
5721 !typeSymbol
.get
<DerivedTypeDetails
>().sequence()) {
5723 "Derived type '%s' in COMMON block must have the BIND or"
5724 " SEQUENCE attribute"_err_en_US
);
5726 CheckCommonBlockDerivedType(name
, typeSymbol
);
5730 specPartState_
.commonBlockObjects
= {};
5733 Symbol
&DeclarationVisitor::MakeCommonBlockSymbol(const parser::Name
&name
) {
5734 return Resolve(name
, currScope().MakeCommonBlock(name
.source
));
5736 Symbol
&DeclarationVisitor::MakeCommonBlockSymbol(
5737 const std::optional
<parser::Name
> &name
) {
5739 return MakeCommonBlockSymbol(*name
);
5741 return MakeCommonBlockSymbol(parser::Name
{});
5745 bool DeclarationVisitor::NameIsKnownOrIntrinsic(const parser::Name
&name
) {
5746 return FindSymbol(name
) || HandleUnrestrictedSpecificIntrinsicFunction(name
);
5749 // Check if this derived type can be in a COMMON block.
5750 void DeclarationVisitor::CheckCommonBlockDerivedType(
5751 const SourceName
&name
, const Symbol
&typeSymbol
) {
5752 if (const auto *scope
{typeSymbol
.scope()}) {
5753 for (const auto &pair
: *scope
) {
5754 const Symbol
&component
{*pair
.second
};
5755 if (component
.attrs().test(Attr::ALLOCATABLE
)) {
5757 "Derived type variable '%s' may not appear in a COMMON block"
5758 " due to ALLOCATABLE component"_err_en_US
,
5759 component
.name(), "Component with ALLOCATABLE attribute"_en_US
);
5762 const auto *details
{component
.detailsIf
<ObjectEntityDetails
>()};
5763 if (component
.test(Symbol::Flag::InDataStmt
) ||
5764 (details
&& details
->init())) {
5766 "Derived type variable '%s' may not appear in a COMMON block due to component with default initialization"_err_en_US
,
5767 component
.name(), "Component with default initialization"_en_US
);
5771 if (const auto *type
{details
->type()}) {
5772 if (const auto *derived
{type
->AsDerived()}) {
5773 const Symbol
&derivedTypeSymbol
{derived
->typeSymbol()};
5774 // Don't call this member function recursively if the derived type
5775 // symbol is the same symbol that is already being processed.
5776 // This can happen when a component is a pointer of the same type
5777 // as its parent component, for instance.
5778 if (derivedTypeSymbol
!= typeSymbol
) {
5779 CheckCommonBlockDerivedType(name
, derivedTypeSymbol
);
5788 bool DeclarationVisitor::HandleUnrestrictedSpecificIntrinsicFunction(
5789 const parser::Name
&name
) {
5790 if (auto interface
{context().intrinsics().IsSpecificIntrinsicFunction(
5791 name
.source
.ToString())}) {
5792 // Unrestricted specific intrinsic function names (e.g., "cos")
5793 // are acceptable as procedure interfaces. The presence of the
5794 // INTRINSIC flag will cause this symbol to have a complete interface
5795 // recreated for it later on demand, but capturing its result type here
5796 // will make GetType() return a correct result without having to
5797 // probe the intrinsics table again.
5799 MakeSymbol(InclusiveScope(), name
.source
, Attrs
{Attr::INTRINSIC
})};
5800 CHECK(interface
->functionResult
.has_value());
5801 evaluate::DynamicType dyType
{
5802 DEREF(interface
->functionResult
->GetTypeAndShape()).type()};
5803 CHECK(common::IsNumericTypeCategory(dyType
.category()));
5804 const DeclTypeSpec
&typeSpec
{
5805 MakeNumericType(dyType
.category(), dyType
.kind())};
5806 ProcEntityDetails details
;
5807 details
.set_type(typeSpec
);
5808 symbol
.set_details(std::move(details
));
5809 symbol
.set(Symbol::Flag::Function
);
5810 if (interface
->IsElemental()) {
5811 SetExplicitAttr(symbol
, Attr::ELEMENTAL
);
5813 if (interface
->IsPure()) {
5814 SetExplicitAttr(symbol
, Attr::PURE
);
5816 Resolve(name
, symbol
);
5823 // Checks for all locality-specs: LOCAL, LOCAL_INIT, and SHARED
5824 bool DeclarationVisitor::PassesSharedLocalityChecks(
5825 const parser::Name
&name
, Symbol
&symbol
) {
5826 if (!IsVariableName(symbol
)) {
5827 SayLocalMustBeVariable(name
, symbol
); // C1124
5830 if (symbol
.owner() == currScope()) { // C1125 and C1126
5831 SayAlreadyDeclared(name
, symbol
);
5837 // Checks for locality-specs LOCAL and LOCAL_INIT
5838 bool DeclarationVisitor::PassesLocalityChecks(
5839 const parser::Name
&name
, Symbol
&symbol
) {
5840 if (IsAllocatable(symbol
)) { // C1128
5841 SayWithDecl(name
, symbol
,
5842 "ALLOCATABLE variable '%s' not allowed in a locality-spec"_err_en_US
);
5845 if (IsOptional(symbol
)) { // C1128
5846 SayWithDecl(name
, symbol
,
5847 "OPTIONAL argument '%s' not allowed in a locality-spec"_err_en_US
);
5850 if (IsIntentIn(symbol
)) { // C1128
5851 SayWithDecl(name
, symbol
,
5852 "INTENT IN argument '%s' not allowed in a locality-spec"_err_en_US
);
5855 if (IsFinalizable(symbol
)) { // C1128
5856 SayWithDecl(name
, symbol
,
5857 "Finalizable variable '%s' not allowed in a locality-spec"_err_en_US
);
5860 if (evaluate::IsCoarray(symbol
)) { // C1128
5862 name
, symbol
, "Coarray '%s' not allowed in a locality-spec"_err_en_US
);
5865 if (const DeclTypeSpec
* type
{symbol
.GetType()}) {
5866 if (type
->IsPolymorphic() && IsDummy(symbol
) &&
5867 !IsPointer(symbol
)) { // C1128
5868 SayWithDecl(name
, symbol
,
5869 "Nonpointer polymorphic argument '%s' not allowed in a "
5870 "locality-spec"_err_en_US
);
5874 if (IsAssumedSizeArray(symbol
)) { // C1128
5875 SayWithDecl(name
, symbol
,
5876 "Assumed size array '%s' not allowed in a locality-spec"_err_en_US
);
5879 if (std::optional
<Message
> whyNot
{WhyNotDefinable(
5880 name
.source
, currScope(), DefinabilityFlags
{}, symbol
)}) {
5881 SayWithReason(name
, symbol
,
5882 "'%s' may not appear in a locality-spec because it is not "
5883 "definable"_err_en_US
,
5884 std::move(*whyNot
));
5887 return PassesSharedLocalityChecks(name
, symbol
);
5890 Symbol
&DeclarationVisitor::FindOrDeclareEnclosingEntity(
5891 const parser::Name
&name
) {
5892 Symbol
*prev
{FindSymbol(name
)};
5894 // Declare the name as an object in the enclosing scope so that
5895 // the name can't be repurposed there later as something else.
5896 prev
= &MakeSymbol(InclusiveScope(), name
.source
, Attrs
{});
5897 ConvertToObjectEntity(*prev
);
5898 ApplyImplicitRules(*prev
);
5903 Symbol
*DeclarationVisitor::DeclareLocalEntity(const parser::Name
&name
) {
5904 Symbol
&prev
{FindOrDeclareEnclosingEntity(name
)};
5905 if (!PassesLocalityChecks(name
, prev
)) {
5908 return &MakeHostAssocSymbol(name
, prev
);
5911 Symbol
*DeclarationVisitor::DeclareStatementEntity(
5912 const parser::DoVariable
&doVar
,
5913 const std::optional
<parser::IntegerTypeSpec
> &type
) {
5914 const parser::Name
&name
{doVar
.thing
.thing
};
5915 const DeclTypeSpec
*declTypeSpec
{nullptr};
5916 if (auto *prev
{FindSymbol(name
)}) {
5917 if (prev
->owner() == currScope()) {
5918 SayAlreadyDeclared(name
, *prev
);
5921 name
.symbol
= nullptr;
5922 declTypeSpec
= prev
->GetType();
5924 Symbol
&symbol
{DeclareEntity
<ObjectEntityDetails
>(name
, {})};
5925 if (!symbol
.has
<ObjectEntityDetails
>()) {
5926 return nullptr; // error was reported in DeclareEntity
5929 declTypeSpec
= ProcessTypeSpec(*type
);
5932 // Subtlety: Don't let a "*length" specifier (if any is pending) affect the
5933 // declaration of this implied DO loop control variable.
5935 common::ScopedSet(charInfo_
.length
, std::optional
<ParamValue
>{})};
5936 SetType(name
, *declTypeSpec
);
5938 ApplyImplicitRules(symbol
);
5940 Symbol
*result
{Resolve(name
, &symbol
)};
5941 AnalyzeExpr(context(), doVar
); // enforce INTEGER type
5945 // Set the type of an entity or report an error.
5946 void DeclarationVisitor::SetType(
5947 const parser::Name
&name
, const DeclTypeSpec
&type
) {
5949 auto &symbol
{*name
.symbol
};
5950 if (charInfo_
.length
) { // Declaration has "*length" (R723)
5951 auto length
{std::move(*charInfo_
.length
)};
5952 charInfo_
.length
.reset();
5953 if (type
.category() == DeclTypeSpec::Character
) {
5954 auto kind
{type
.characterTypeSpec().kind()};
5955 // Recurse with correct type.
5957 currScope().MakeCharacterType(std::move(length
), std::move(kind
)));
5961 "A length specifier cannot be used to declare the non-character entity '%s'"_err_en_US
);
5964 if (auto *proc
{symbol
.detailsIf
<ProcEntityDetails
>()}) {
5965 if (proc
->procInterface()) {
5967 "'%s' has an explicit interface and may not also have a type"_err_en_US
);
5968 context().SetError(symbol
);
5972 auto *prevType
{symbol
.GetType()};
5974 symbol
.SetType(type
);
5975 } else if (symbol
.has
<UseDetails
>()) {
5976 // error recovery case, redeclaration of use-associated name
5977 } else if (HadForwardRef(symbol
)) {
5978 // error recovery after use of host-associated name
5979 } else if (!symbol
.test(Symbol::Flag::Implicit
)) {
5981 name
, symbol
, "The type of '%s' has already been declared"_err_en_US
);
5982 context().SetError(symbol
);
5983 } else if (type
!= *prevType
) {
5984 SayWithDecl(name
, symbol
,
5985 "The type of '%s' has already been implicitly declared"_err_en_US
);
5986 context().SetError(symbol
);
5988 symbol
.set(Symbol::Flag::Implicit
, false);
5992 std::optional
<DerivedTypeSpec
> DeclarationVisitor::ResolveDerivedType(
5993 const parser::Name
&name
) {
5994 Scope
&outer
{NonDerivedTypeScope()};
5995 Symbol
*symbol
{FindSymbol(outer
, name
)};
5996 Symbol
*ultimate
{symbol
? &symbol
->GetUltimate() : nullptr};
5997 auto *generic
{ultimate
? ultimate
->detailsIf
<GenericDetails
>() : nullptr};
5999 if (Symbol
* genDT
{generic
->derivedType()}) {
6004 if (!symbol
|| symbol
->has
<UnknownDetails
>() ||
6005 (generic
&& &ultimate
->owner() == &outer
)) {
6006 if (allowForwardReferenceToDerivedType()) {
6008 symbol
= &MakeSymbol(outer
, name
.source
, Attrs
{});
6009 Resolve(name
, *symbol
);
6010 } else if (generic
) {
6011 // forward ref to type with later homonymous generic
6012 symbol
= &outer
.MakeSymbol(name
.source
, Attrs
{}, UnknownDetails
{});
6013 generic
->set_derivedType(*symbol
);
6014 name
.symbol
= symbol
;
6016 DerivedTypeDetails details
;
6017 details
.set_isForwardReferenced(true);
6018 symbol
->set_details(std::move(details
));
6020 Say(name
, "Derived type '%s' not found"_err_en_US
);
6021 return std::nullopt
;
6024 if (CheckUseError(name
)) {
6025 return std::nullopt
;
6027 symbol
= &symbol
->GetUltimate();
6028 if (symbol
->has
<DerivedTypeDetails
>()) {
6029 return DerivedTypeSpec
{name
.source
, *symbol
};
6031 Say(name
, "'%s' is not a derived type"_err_en_US
);
6032 return std::nullopt
;
6036 std::optional
<DerivedTypeSpec
> DeclarationVisitor::ResolveExtendsType(
6037 const parser::Name
&typeName
, const parser::Name
*extendsName
) {
6039 return std::nullopt
;
6040 } else if (typeName
.source
== extendsName
->source
) {
6041 Say(extendsName
->source
,
6042 "Derived type '%s' cannot extend itself"_err_en_US
);
6043 return std::nullopt
;
6045 return ResolveDerivedType(*extendsName
);
6049 Symbol
*DeclarationVisitor::NoteInterfaceName(const parser::Name
&name
) {
6050 // The symbol is checked later by CheckExplicitInterface() and
6051 // CheckBindings(). It can be a forward reference.
6052 if (!NameIsKnownOrIntrinsic(name
)) {
6053 Symbol
&symbol
{MakeSymbol(InclusiveScope(), name
.source
, Attrs
{})};
6054 Resolve(name
, symbol
);
6059 void DeclarationVisitor::CheckExplicitInterface(const parser::Name
&name
) {
6060 if (const Symbol
* symbol
{name
.symbol
}) {
6061 const Symbol
&ultimate
{symbol
->GetUltimate()};
6062 if (!context().HasError(*symbol
) && !context().HasError(ultimate
) &&
6063 !ultimate
.HasExplicitInterface()) {
6065 "'%s' must be an abstract interface or a procedure with "
6066 "an explicit interface"_err_en_US
,
6072 // Create a symbol for a type parameter, component, or procedure binding in
6073 // the current derived type scope. Return false on error.
6074 Symbol
*DeclarationVisitor::MakeTypeSymbol(
6075 const parser::Name
&name
, Details
&&details
) {
6076 return Resolve(name
, MakeTypeSymbol(name
.source
, std::move(details
)));
6078 Symbol
*DeclarationVisitor::MakeTypeSymbol(
6079 const SourceName
&name
, Details
&&details
) {
6080 Scope
&derivedType
{currScope()};
6081 CHECK(derivedType
.IsDerivedType());
6082 if (auto *symbol
{FindInScope(derivedType
, name
)}) { // C742
6084 "Type parameter, component, or procedure binding '%s'"
6085 " already defined in this type"_err_en_US
,
6086 *symbol
, "Previous definition of '%s'"_en_US
);
6089 auto attrs
{GetAttrs()};
6090 // Apply binding-private-stmt if present and this is a procedure binding
6091 if (derivedTypeInfo_
.privateBindings
&&
6092 !attrs
.HasAny({Attr::PUBLIC
, Attr::PRIVATE
}) &&
6093 std::holds_alternative
<ProcBindingDetails
>(details
)) {
6094 attrs
.set(Attr::PRIVATE
);
6096 Symbol
&result
{MakeSymbol(name
, attrs
, std::move(details
))};
6097 if (result
.has
<TypeParamDetails
>()) {
6098 derivedType
.symbol()->get
<DerivedTypeDetails
>().add_paramDecl(result
);
6104 // Return true if it is ok to declare this component in the current scope.
6105 // Otherwise, emit an error and return false.
6106 bool DeclarationVisitor::OkToAddComponent(
6107 const parser::Name
&name
, const Symbol
*extends
) {
6108 for (const Scope
*scope
{&currScope()}; scope
;) {
6109 CHECK(scope
->IsDerivedType());
6110 if (auto *prev
{FindInScope(*scope
, name
.source
)}) {
6111 std::optional
<parser::MessageFixedText
> msg
;
6112 if (context().HasError(*prev
)) { // don't pile on
6113 } else if (extends
) {
6114 msg
= "Type cannot be extended as it has a component named"
6116 } else if (CheckAccessibleSymbol(currScope(), *prev
)) {
6117 // inaccessible component -- redeclaration is ok
6118 msg
= "Component '%s' is inaccessibly declared in or as a "
6119 "parent of this derived type"_warn_en_US
;
6120 } else if (prev
->test(Symbol::Flag::ParentComp
)) {
6121 msg
= "'%s' is a parent type of this type and so cannot be"
6122 " a component"_err_en_US
;
6123 } else if (scope
== &currScope()) {
6124 msg
= "Component '%s' is already declared in this"
6125 " derived type"_err_en_US
;
6127 msg
= "Component '%s' is already declared in a parent of this"
6128 " derived type"_err_en_US
;
6132 name
, std::move(*msg
), *prev
, "Previous declaration of '%s'"_en_US
);
6133 if (msg
->severity() == parser::Severity::Error
) {
6134 Resolve(name
, *prev
);
6139 if (scope
== &currScope() && extends
) {
6140 // The parent component has not yet been added to the scope.
6141 scope
= extends
->scope();
6143 scope
= scope
->GetDerivedTypeParent();
6149 ParamValue
DeclarationVisitor::GetParamValue(
6150 const parser::TypeParamValue
&x
, common::TypeParamAttr attr
) {
6151 return common::visit(
6153 [=](const parser::ScalarIntExpr
&x
) { // C704
6154 return ParamValue
{EvaluateIntExpr(x
), attr
};
6156 [=](const parser::Star
&) { return ParamValue::Assumed(attr
); },
6157 [=](const parser::TypeParamValue::Deferred
&) {
6158 return ParamValue::Deferred(attr
);
6164 // ConstructVisitor implementation
6166 void ConstructVisitor::ResolveIndexName(
6167 const parser::ConcurrentControl
&control
) {
6168 const parser::Name
&name
{std::get
<parser::Name
>(control
.t
)};
6169 auto *prev
{FindSymbol(name
)};
6171 if (prev
->owner().kind() == Scope::Kind::Forall
||
6172 prev
->owner() == currScope()) {
6173 SayAlreadyDeclared(name
, *prev
);
6176 name
.symbol
= nullptr;
6178 auto &symbol
{DeclareObjectEntity(name
)};
6179 if (symbol
.GetType()) {
6180 // type came from explicit type-spec
6182 ApplyImplicitRules(symbol
);
6184 const Symbol
&prevRoot
{prev
->GetUltimate()};
6185 // prev could be host- use- or construct-associated with another symbol
6186 if (!prevRoot
.has
<ObjectEntityDetails
>() &&
6187 !prevRoot
.has
<AssocEntityDetails
>()) {
6188 Say2(name
, "Index name '%s' conflicts with existing identifier"_err_en_US
,
6189 *prev
, "Previous declaration of '%s'"_en_US
);
6190 context().SetError(symbol
);
6193 if (const auto *type
{prevRoot
.GetType()}) {
6194 symbol
.SetType(*type
);
6196 if (prevRoot
.IsObjectArray()) {
6197 SayWithDecl(name
, *prev
, "Index variable '%s' is not scalar"_err_en_US
);
6202 EvaluateExpr(parser::Scalar
{parser::Integer
{common::Clone(name
)}});
6205 // We need to make sure that all of the index-names get declared before the
6206 // expressions in the loop control are evaluated so that references to the
6207 // index-names in the expressions are correctly detected.
6208 bool ConstructVisitor::Pre(const parser::ConcurrentHeader
&header
) {
6209 BeginDeclTypeSpec();
6210 Walk(std::get
<std::optional
<parser::IntegerTypeSpec
>>(header
.t
));
6211 const auto &controls
{
6212 std::get
<std::list
<parser::ConcurrentControl
>>(header
.t
)};
6213 for (const auto &control
: controls
) {
6214 ResolveIndexName(control
);
6217 Walk(std::get
<std::optional
<parser::ScalarLogicalExpr
>>(header
.t
));
6222 bool ConstructVisitor::Pre(const parser::LocalitySpec::Local
&x
) {
6223 for (auto &name
: x
.v
) {
6224 if (auto *symbol
{DeclareLocalEntity(name
)}) {
6225 symbol
->set(Symbol::Flag::LocalityLocal
);
6231 bool ConstructVisitor::Pre(const parser::LocalitySpec::LocalInit
&x
) {
6232 for (auto &name
: x
.v
) {
6233 if (auto *symbol
{DeclareLocalEntity(name
)}) {
6234 symbol
->set(Symbol::Flag::LocalityLocalInit
);
6240 bool ConstructVisitor::Pre(const parser::LocalitySpec::Shared
&x
) {
6241 for (const auto &name
: x
.v
) {
6242 if (!FindSymbol(name
)) {
6244 "Variable '%s' with SHARED locality implicitly declared"_warn_en_US
);
6246 Symbol
&prev
{FindOrDeclareEnclosingEntity(name
)};
6247 if (PassesSharedLocalityChecks(name
, prev
)) {
6248 MakeHostAssocSymbol(name
, prev
).set(Symbol::Flag::LocalityShared
);
6254 bool ConstructVisitor::Pre(const parser::AcSpec
&x
) {
6255 ProcessTypeSpec(x
.type
);
6260 // Section 19.4, paragraph 5 says that each ac-do-variable has the scope of the
6261 // enclosing ac-implied-do
6262 bool ConstructVisitor::Pre(const parser::AcImpliedDo
&x
) {
6263 auto &values
{std::get
<std::list
<parser::AcValue
>>(x
.t
)};
6264 auto &control
{std::get
<parser::AcImpliedDoControl
>(x
.t
)};
6265 auto &type
{std::get
<std::optional
<parser::IntegerTypeSpec
>>(control
.t
)};
6266 auto &bounds
{std::get
<parser::AcImpliedDoControl::Bounds
>(control
.t
)};
6267 // F'2018 has the scope of the implied DO variable covering the entire
6268 // implied DO production (19.4(5)), which seems wrong in cases where the name
6269 // of the implied DO variable appears in one of the bound expressions. Thus
6270 // this extension, which shrinks the scope of the variable to exclude the
6271 // expressions in the bounds.
6272 auto restore
{BeginCheckOnIndexUseInOwnBounds(bounds
.name
)};
6276 EndCheckOnIndexUseInOwnBounds(restore
);
6277 PushScope(Scope::Kind::ImpliedDos
, nullptr);
6278 DeclareStatementEntity(bounds
.name
, type
);
6284 bool ConstructVisitor::Pre(const parser::DataImpliedDo
&x
) {
6285 auto &objects
{std::get
<std::list
<parser::DataIDoObject
>>(x
.t
)};
6286 auto &type
{std::get
<std::optional
<parser::IntegerTypeSpec
>>(x
.t
)};
6287 auto &bounds
{std::get
<parser::DataImpliedDo::Bounds
>(x
.t
)};
6288 // See comment in Pre(AcImpliedDo) above.
6289 auto restore
{BeginCheckOnIndexUseInOwnBounds(bounds
.name
)};
6293 EndCheckOnIndexUseInOwnBounds(restore
);
6294 bool pushScope
{currScope().kind() != Scope::Kind::ImpliedDos
};
6296 PushScope(Scope::Kind::ImpliedDos
, nullptr);
6298 DeclareStatementEntity(bounds
.name
, type
);
6306 // Sets InDataStmt flag on a variable (or misidentified function) in a DATA
6307 // statement so that the predicate IsInitialized() will be true
6308 // during semantic analysis before the symbol's initializer is constructed.
6309 bool ConstructVisitor::Pre(const parser::DataIDoObject
&x
) {
6312 [&](const parser::Scalar
<Indirection
<parser::Designator
>> &y
) {
6313 Walk(y
.thing
.value());
6314 const parser::Name
&first
{parser::GetFirstName(y
.thing
.value())};
6316 first
.symbol
->set(Symbol::Flag::InDataStmt
);
6319 [&](const Indirection
<parser::DataImpliedDo
> &y
) { Walk(y
.value()); },
6325 bool ConstructVisitor::Pre(const parser::DataStmtObject
&x
) {
6326 // Subtle: DATA statements may appear in both the specification and
6327 // execution parts, but should be treated as if in the execution part
6328 // for purposes of implicit variable declaration vs. host association.
6329 // When a name first appears as an object in a DATA statement, it should
6330 // be implicitly declared locally as if it had been assigned.
6331 auto flagRestorer
{common::ScopedSet(inSpecificationPart_
, false)};
6332 common::visit(common::visitors
{
6333 [&](const Indirection
<parser::Variable
> &y
) {
6335 const parser::Name
&first
{
6336 parser::GetFirstName(y
.value())};
6338 first
.symbol
->set(Symbol::Flag::InDataStmt
);
6341 [&](const parser::DataImpliedDo
&y
) {
6342 PushScope(Scope::Kind::ImpliedDos
, nullptr);
6351 bool ConstructVisitor::Pre(const parser::DataStmtValue
&x
) {
6352 const auto &data
{std::get
<parser::DataStmtConstant
>(x
.t
)};
6353 auto &mutableData
{const_cast<parser::DataStmtConstant
&>(data
)};
6354 if (auto *elem
{parser::Unwrap
<parser::ArrayElement
>(mutableData
)}) {
6355 if (const auto *name
{std::get_if
<parser::Name
>(&elem
->base
.u
)}) {
6356 if (const Symbol
* symbol
{FindSymbol(*name
)}) {
6357 const Symbol
&ultimate
{symbol
->GetUltimate()};
6358 if (ultimate
.has
<DerivedTypeDetails
>()) {
6359 mutableData
.u
= elem
->ConvertToStructureConstructor(
6360 DerivedTypeSpec
{name
->source
, ultimate
});
6368 bool ConstructVisitor::Pre(const parser::DoConstruct
&x
) {
6369 if (x
.IsDoConcurrent()) {
6370 PushScope(Scope::Kind::OtherConstruct
, nullptr);
6374 void ConstructVisitor::Post(const parser::DoConstruct
&x
) {
6375 if (x
.IsDoConcurrent()) {
6380 bool ConstructVisitor::Pre(const parser::ForallConstruct
&) {
6381 PushScope(Scope::Kind::Forall
, nullptr);
6384 void ConstructVisitor::Post(const parser::ForallConstruct
&) { PopScope(); }
6385 bool ConstructVisitor::Pre(const parser::ForallStmt
&) {
6386 PushScope(Scope::Kind::Forall
, nullptr);
6389 void ConstructVisitor::Post(const parser::ForallStmt
&) { PopScope(); }
6391 bool ConstructVisitor::Pre(const parser::BlockStmt
&x
) {
6393 PushScope(Scope::Kind::BlockConstruct
, nullptr);
6396 bool ConstructVisitor::Pre(const parser::EndBlockStmt
&x
) {
6402 void ConstructVisitor::Post(const parser::Selector
&x
) {
6403 GetCurrentAssociation().selector
= ResolveSelector(x
);
6406 void ConstructVisitor::Post(const parser::AssociateStmt
&x
) {
6408 PushScope(Scope::Kind::OtherConstruct
, nullptr);
6409 const auto assocCount
{std::get
<std::list
<parser::Association
>>(x
.t
).size()};
6410 for (auto nthLastAssoc
{assocCount
}; nthLastAssoc
> 0; --nthLastAssoc
) {
6411 SetCurrentAssociation(nthLastAssoc
);
6412 if (auto *symbol
{MakeAssocEntity()}) {
6413 if (ExtractCoarrayRef(GetCurrentAssociation().selector
.expr
)) { // C1103
6414 Say("Selector must not be a coindexed object"_err_en_US
);
6416 SetTypeFromAssociation(*symbol
);
6417 SetAttrsFromAssociation(*symbol
);
6420 PopAssociation(assocCount
);
6423 void ConstructVisitor::Post(const parser::EndAssociateStmt
&x
) {
6428 bool ConstructVisitor::Pre(const parser::Association
&x
) {
6430 const auto &name
{std::get
<parser::Name
>(x
.t
)};
6431 GetCurrentAssociation().name
= &name
;
6435 bool ConstructVisitor::Pre(const parser::ChangeTeamStmt
&x
) {
6437 PushScope(Scope::Kind::OtherConstruct
, nullptr);
6442 void ConstructVisitor::Post(const parser::CoarrayAssociation
&x
) {
6443 const auto &decl
{std::get
<parser::CodimensionDecl
>(x
.t
)};
6444 const auto &name
{std::get
<parser::Name
>(decl
.t
)};
6445 if (auto *symbol
{FindInScope(name
)}) {
6446 const auto &selector
{std::get
<parser::Selector
>(x
.t
)};
6447 if (auto sel
{ResolveSelector(selector
)}) {
6448 const Symbol
*whole
{UnwrapWholeSymbolDataRef(sel
.expr
)};
6449 if (!whole
|| whole
->Corank() == 0) {
6450 Say(sel
.source
, // C1116
6451 "Selector in coarray association must name a coarray"_err_en_US
);
6452 } else if (auto dynType
{sel
.expr
->GetType()}) {
6453 if (!symbol
->GetType()) {
6454 symbol
->SetType(ToDeclTypeSpec(std::move(*dynType
)));
6461 void ConstructVisitor::Post(const parser::EndChangeTeamStmt
&x
) {
6467 bool ConstructVisitor::Pre(const parser::SelectTypeConstruct
&) {
6472 void ConstructVisitor::Post(const parser::SelectTypeConstruct
&) {
6476 void ConstructVisitor::Post(const parser::SelectTypeStmt
&x
) {
6477 auto &association
{GetCurrentAssociation()};
6478 if (const std::optional
<parser::Name
> &name
{std::get
<1>(x
.t
)}) {
6479 // This isn't a name in the current scope, it is in each TypeGuardStmt
6480 MakePlaceholder(*name
, MiscDetails::Kind::SelectTypeAssociateName
);
6481 association
.name
= &*name
;
6482 if (ExtractCoarrayRef(association
.selector
.expr
)) { // C1103
6483 Say("Selector must not be a coindexed object"_err_en_US
);
6485 if (association
.selector
.expr
) {
6486 auto exprType
{association
.selector
.expr
->GetType()};
6487 if (exprType
&& !exprType
->IsPolymorphic()) { // C1159
6488 Say(association
.selector
.source
,
6489 "Selector '%s' in SELECT TYPE statement must be "
6490 "polymorphic"_err_en_US
);
6495 whole
{UnwrapWholeSymbolDataRef(association
.selector
.expr
)}) {
6496 ConvertToObjectEntity(const_cast<Symbol
&>(*whole
));
6497 if (!IsVariableName(*whole
)) {
6498 Say(association
.selector
.source
, // C901
6499 "Selector is not a variable"_err_en_US
);
6502 if (const DeclTypeSpec
* type
{whole
->GetType()}) {
6503 if (!type
->IsPolymorphic()) { // C1159
6504 Say(association
.selector
.source
,
6505 "Selector '%s' in SELECT TYPE statement must be "
6506 "polymorphic"_err_en_US
);
6510 Say(association
.selector
.source
, // C1157
6511 "Selector is not a named variable: 'associate-name =>' is required"_err_en_US
);
6517 void ConstructVisitor::Post(const parser::SelectRankStmt
&x
) {
6518 auto &association
{GetCurrentAssociation()};
6519 if (const std::optional
<parser::Name
> &name
{std::get
<1>(x
.t
)}) {
6520 // This isn't a name in the current scope, it is in each SelectRankCaseStmt
6521 MakePlaceholder(*name
, MiscDetails::Kind::SelectRankAssociateName
);
6522 association
.name
= &*name
;
6526 bool ConstructVisitor::Pre(const parser::SelectTypeConstruct::TypeCase
&) {
6527 PushScope(Scope::Kind::OtherConstruct
, nullptr);
6530 void ConstructVisitor::Post(const parser::SelectTypeConstruct::TypeCase
&) {
6534 bool ConstructVisitor::Pre(const parser::SelectRankConstruct::RankCase
&) {
6535 PushScope(Scope::Kind::OtherConstruct
, nullptr);
6538 void ConstructVisitor::Post(const parser::SelectRankConstruct::RankCase
&) {
6542 bool ConstructVisitor::Pre(const parser::TypeGuardStmt::Guard
&x
) {
6543 if (std::holds_alternative
<parser::DerivedTypeSpec
>(x
.u
)) {
6545 SetDeclTypeSpecCategory(DeclTypeSpec::Category::ClassDerived
);
6550 void ConstructVisitor::Post(const parser::TypeGuardStmt::Guard
&x
) {
6551 if (auto *symbol
{MakeAssocEntity()}) {
6552 if (std::holds_alternative
<parser::Default
>(x
.u
)) {
6553 SetTypeFromAssociation(*symbol
);
6554 } else if (const auto *type
{GetDeclTypeSpec()}) {
6555 symbol
->SetType(*type
);
6557 SetAttrsFromAssociation(*symbol
);
6561 void ConstructVisitor::Post(const parser::SelectRankCaseStmt::Rank
&x
) {
6562 if (auto *symbol
{MakeAssocEntity()}) {
6563 SetTypeFromAssociation(*symbol
);
6564 SetAttrsFromAssociation(*symbol
);
6565 if (const auto *init
{std::get_if
<parser::ScalarIntConstantExpr
>(&x
.u
)}) {
6566 if (auto val
{EvaluateInt64(context(), *init
)}) {
6567 auto &details
{symbol
->get
<AssocEntityDetails
>()};
6568 details
.set_rank(*val
);
6574 bool ConstructVisitor::Pre(const parser::SelectRankConstruct
&) {
6579 void ConstructVisitor::Post(const parser::SelectRankConstruct
&) {
6583 bool ConstructVisitor::CheckDef(const std::optional
<parser::Name
> &x
) {
6584 if (x
&& !x
->symbol
) {
6585 // Construct names are not scoped by BLOCK in the standard, but many,
6586 // but not all, compilers do treat them as if they were so scoped.
6587 if (Symbol
* inner
{FindInScope(currScope(), *x
)}) {
6588 SayAlreadyDeclared(*x
, *inner
);
6591 other
{FindInScopeOrBlockConstructs(InclusiveScope(), x
->source
)}) {
6592 SayWithDecl(*x
, *other
,
6593 "The construct name '%s' should be distinct at the subprogram level"_port_en_US
);
6595 MakeSymbol(*x
, MiscDetails
{MiscDetails::Kind::ConstructName
});
6601 void ConstructVisitor::CheckRef(const std::optional
<parser::Name
> &x
) {
6603 // Just add an occurrence of this name; checking is done in ValidateLabels
6608 // Make a symbol for the associating entity of the current association.
6609 Symbol
*ConstructVisitor::MakeAssocEntity() {
6610 Symbol
*symbol
{nullptr};
6611 auto &association
{GetCurrentAssociation()};
6612 if (association
.name
) {
6613 symbol
= &MakeSymbol(*association
.name
, UnknownDetails
{});
6614 if (symbol
->has
<AssocEntityDetails
>() && symbol
->owner() == currScope()) {
6615 Say(*association
.name
, // C1102
6616 "The associate name '%s' is already used in this associate statement"_err_en_US
);
6619 } else if (const Symbol
*
6620 whole
{UnwrapWholeSymbolDataRef(association
.selector
.expr
)}) {
6621 symbol
= &MakeSymbol(whole
->name());
6625 if (auto &expr
{association
.selector
.expr
}) {
6626 symbol
->set_details(AssocEntityDetails
{common::Clone(*expr
)});
6628 symbol
->set_details(AssocEntityDetails
{});
6633 // Set the type of symbol based on the current association selector.
6634 void ConstructVisitor::SetTypeFromAssociation(Symbol
&symbol
) {
6635 auto &details
{symbol
.get
<AssocEntityDetails
>()};
6636 const MaybeExpr
*pexpr
{&details
.expr()};
6638 pexpr
= &GetCurrentAssociation().selector
.expr
;
6641 const SomeExpr
&expr
{**pexpr
};
6642 if (std::optional
<evaluate::DynamicType
> type
{expr
.GetType()}) {
6643 if (const auto *charExpr
{
6644 evaluate::UnwrapExpr
<evaluate::Expr
<evaluate::SomeCharacter
>>(
6646 symbol
.SetType(ToDeclTypeSpec(std::move(*type
),
6647 FoldExpr(common::visit(
6648 [](const auto &kindChar
) { return kindChar
.LEN(); },
6651 symbol
.SetType(ToDeclTypeSpec(std::move(*type
)));
6654 // BOZ literals, procedure designators, &c. are not acceptable
6655 Say(symbol
.name(), "Associate name '%s' must have a type"_err_en_US
);
6660 // If current selector is a variable, set some of its attributes on symbol.
6661 void ConstructVisitor::SetAttrsFromAssociation(Symbol
&symbol
) {
6662 Attrs attrs
{evaluate::GetAttrs(GetCurrentAssociation().selector
.expr
)};
6664 attrs
& Attrs
{Attr::TARGET
, Attr::ASYNCHRONOUS
, Attr::VOLATILE
};
6665 if (attrs
.test(Attr::POINTER
)) {
6666 SetImplicitAttr(symbol
, Attr::TARGET
);
6670 ConstructVisitor::Selector
ConstructVisitor::ResolveSelector(
6671 const parser::Selector
&x
) {
6672 return common::visit(common::visitors
{
6673 [&](const parser::Expr
&expr
) {
6674 return Selector
{expr
.source
, EvaluateExpr(x
)};
6676 [&](const parser::Variable
&var
) {
6677 return Selector
{var
.GetSource(), EvaluateExpr(x
)};
6683 // Set the current association to the nth to the last association on the
6684 // association stack. The top of the stack is at n = 1. This allows access
6685 // to the interior of a list of associations at the top of the stack.
6686 void ConstructVisitor::SetCurrentAssociation(std::size_t n
) {
6687 CHECK(n
> 0 && n
<= associationStack_
.size());
6688 currentAssociation_
= &associationStack_
[associationStack_
.size() - n
];
6691 ConstructVisitor::Association
&ConstructVisitor::GetCurrentAssociation() {
6692 CHECK(currentAssociation_
);
6693 return *currentAssociation_
;
6696 void ConstructVisitor::PushAssociation() {
6697 associationStack_
.emplace_back(Association
{});
6698 currentAssociation_
= &associationStack_
.back();
6701 void ConstructVisitor::PopAssociation(std::size_t count
) {
6702 CHECK(count
> 0 && count
<= associationStack_
.size());
6703 associationStack_
.resize(associationStack_
.size() - count
);
6704 currentAssociation_
=
6705 associationStack_
.empty() ? nullptr : &associationStack_
.back();
6708 const DeclTypeSpec
&ConstructVisitor::ToDeclTypeSpec(
6709 evaluate::DynamicType
&&type
) {
6710 switch (type
.category()) {
6711 SWITCH_COVERS_ALL_CASES
6712 case common::TypeCategory::Integer
:
6713 case common::TypeCategory::Real
:
6714 case common::TypeCategory::Complex
:
6715 return context().MakeNumericType(type
.category(), type
.kind());
6716 case common::TypeCategory::Logical
:
6717 return context().MakeLogicalType(type
.kind());
6718 case common::TypeCategory::Derived
:
6719 if (type
.IsAssumedType()) {
6720 return currScope().MakeTypeStarType();
6721 } else if (type
.IsUnlimitedPolymorphic()) {
6722 return currScope().MakeClassStarType();
6724 return currScope().MakeDerivedType(
6725 type
.IsPolymorphic() ? DeclTypeSpec::ClassDerived
6726 : DeclTypeSpec::TypeDerived
,
6727 common::Clone(type
.GetDerivedTypeSpec())
6731 case common::TypeCategory::Character
:
6736 const DeclTypeSpec
&ConstructVisitor::ToDeclTypeSpec(
6737 evaluate::DynamicType
&&type
, MaybeSubscriptIntExpr
&&length
) {
6738 CHECK(type
.category() == common::TypeCategory::Character
);
6740 return currScope().MakeCharacterType(
6741 ParamValue
{SomeIntExpr
{*std::move(length
)}, common::TypeParamAttr::Len
},
6742 KindExpr
{type
.kind()});
6744 return currScope().MakeCharacterType(
6745 ParamValue::Deferred(common::TypeParamAttr::Len
),
6746 KindExpr
{type
.kind()});
6750 // ResolveNamesVisitor implementation
6752 bool ResolveNamesVisitor::Pre(const parser::FunctionReference
&x
) {
6753 HandleCall(Symbol::Flag::Function
, x
.v
);
6756 bool ResolveNamesVisitor::Pre(const parser::CallStmt
&x
) {
6757 HandleCall(Symbol::Flag::Subroutine
, x
.v
);
6761 bool ResolveNamesVisitor::Pre(const parser::ImportStmt
&x
) {
6762 auto &scope
{currScope()};
6763 // Check C896 and C899: where IMPORT statements are allowed
6764 switch (scope
.kind()) {
6765 case Scope::Kind::Module
:
6766 if (scope
.IsModule()) {
6767 Say("IMPORT is not allowed in a module scoping unit"_err_en_US
);
6769 } else if (x
.kind
== common::ImportKind::None
) {
6770 Say("IMPORT,NONE is not allowed in a submodule scoping unit"_err_en_US
);
6774 case Scope::Kind::MainProgram
:
6775 Say("IMPORT is not allowed in a main program scoping unit"_err_en_US
);
6777 case Scope::Kind::Subprogram
:
6778 if (scope
.parent().IsGlobal()) {
6779 Say("IMPORT is not allowed in an external subprogram scoping unit"_err_en_US
);
6783 case Scope::Kind::BlockData
: // C1415 (in part)
6784 Say("IMPORT is not allowed in a BLOCK DATA subprogram"_err_en_US
);
6788 if (auto error
{scope
.SetImportKind(x
.kind
)}) {
6789 Say(std::move(*error
));
6791 for (auto &name
: x
.names
) {
6792 if (FindSymbol(scope
.parent(), name
)) {
6793 scope
.add_importName(name
.source
);
6795 Say(name
, "'%s' not found in host scope"_err_en_US
);
6798 prevImportStmt_
= currStmtSource();
6802 const parser::Name
*DeclarationVisitor::ResolveStructureComponent(
6803 const parser::StructureComponent
&x
) {
6804 return FindComponent(ResolveDataRef(x
.base
), x
.component
);
6807 const parser::Name
*DeclarationVisitor::ResolveDesignator(
6808 const parser::Designator
&x
) {
6809 return common::visit(
6811 [&](const parser::DataRef
&x
) { return ResolveDataRef(x
); },
6812 [&](const parser::Substring
&x
) {
6813 Walk(std::get
<parser::SubstringRange
>(x
.t
).t
);
6814 return ResolveDataRef(std::get
<parser::DataRef
>(x
.t
));
6820 const parser::Name
*DeclarationVisitor::ResolveDataRef(
6821 const parser::DataRef
&x
) {
6822 return common::visit(
6824 [=](const parser::Name
&y
) { return ResolveName(y
); },
6825 [=](const Indirection
<parser::StructureComponent
> &y
) {
6826 return ResolveStructureComponent(y
.value());
6828 [&](const Indirection
<parser::ArrayElement
> &y
) {
6829 Walk(y
.value().subscripts
);
6830 const parser::Name
*name
{ResolveDataRef(y
.value().base
)};
6831 if (name
&& name
->symbol
) {
6832 if (!IsProcedure(*name
->symbol
)) {
6833 ConvertToObjectEntity(*name
->symbol
);
6834 } else if (!context().HasError(*name
->symbol
)) {
6835 SayWithDecl(*name
, *name
->symbol
,
6836 "Cannot reference function '%s' as data"_err_en_US
);
6841 [&](const Indirection
<parser::CoindexedNamedObject
> &y
) {
6842 Walk(y
.value().imageSelector
);
6843 return ResolveDataRef(y
.value().base
);
6849 // If implicit types are allowed, ensure name is in the symbol table.
6850 // Otherwise, report an error if it hasn't been declared.
6851 const parser::Name
*DeclarationVisitor::ResolveName(const parser::Name
&name
) {
6853 if (CheckForHostAssociatedImplicit(name
)) {
6854 NotePossibleBadForwardRef(name
);
6857 if (Symbol
* symbol
{name
.symbol
}) {
6858 if (CheckUseError(name
)) {
6859 return nullptr; // reported an error
6861 NotePossibleBadForwardRef(name
);
6862 symbol
->set(Symbol::Flag::ImplicitOrError
, false);
6863 if (IsUplevelReference(*symbol
)) {
6864 MakeHostAssocSymbol(name
, *symbol
);
6865 } else if (IsDummy(*symbol
) ||
6866 (!symbol
->GetType() && FindCommonBlockContaining(*symbol
))) {
6867 CheckEntryDummyUse(name
.source
, symbol
);
6868 ConvertToObjectEntity(*symbol
);
6869 ApplyImplicitRules(*symbol
);
6871 if (checkIndexUseInOwnBounds_
&&
6872 *checkIndexUseInOwnBounds_
== name
.source
&& !InModuleFile()) {
6874 "Implied DO index '%s' uses an object of the same name in its bounds expressions"_port_en_US
,
6879 if (isImplicitNoneType()) {
6880 Say(name
, "No explicit type declared for '%s'"_err_en_US
);
6883 // Create the symbol then ensure it is accessible
6884 if (checkIndexUseInOwnBounds_
&& *checkIndexUseInOwnBounds_
== name
.source
) {
6886 "Implied DO index '%s' uses itself in its own bounds expressions"_err_en_US
,
6889 MakeSymbol(InclusiveScope(), name
.source
, Attrs
{});
6890 auto *symbol
{FindSymbol(name
)};
6893 "'%s' from host scoping unit is not accessible due to IMPORT"_err_en_US
);
6896 ConvertToObjectEntity(*symbol
);
6897 ApplyImplicitRules(*symbol
);
6898 NotePossibleBadForwardRef(name
);
6902 // A specification expression may refer to a symbol in the host procedure that
6903 // is implicitly typed. Because specification parts are processed before
6904 // execution parts, this may be the first time we see the symbol. It can't be a
6905 // local in the current scope (because it's in a specification expression) so
6906 // either it is implicitly declared in the host procedure or it is an error.
6907 // We create a symbol in the host assuming it is the former; if that proves to
6908 // be wrong we report an error later in CheckDeclarations().
6909 bool DeclarationVisitor::CheckForHostAssociatedImplicit(
6910 const parser::Name
&name
) {
6911 if (!inSpecificationPart_
) {
6915 ApplyImplicitRules(*name
.symbol
, true);
6918 Scope
*host
{GetHostProcedure()};
6919 if (!host
|| isImplicitNoneType(*host
)) {
6923 hostSymbol
= &MakeSymbol(*host
, name
.source
, Attrs
{});
6924 ConvertToObjectEntity(*hostSymbol
);
6925 ApplyImplicitRules(*hostSymbol
);
6926 hostSymbol
->set(Symbol::Flag::ImplicitOrError
);
6927 } else if (name
.symbol
->test(Symbol::Flag::ImplicitOrError
)) {
6928 hostSymbol
= name
.symbol
;
6932 Symbol
&symbol
{MakeHostAssocSymbol(name
, *hostSymbol
)};
6933 if (isImplicitNoneType()) {
6934 symbol
.get
<HostAssocDetails
>().implicitOrExplicitTypeError
= true;
6936 symbol
.get
<HostAssocDetails
>().implicitOrSpecExprError
= true;
6941 bool DeclarationVisitor::IsUplevelReference(const Symbol
&symbol
) {
6942 const Scope
&symbolUnit
{GetProgramUnitContaining(symbol
)};
6943 if (symbolUnit
== GetProgramUnitContaining(currScope())) {
6946 Scope::Kind kind
{symbolUnit
.kind()};
6947 return kind
== Scope::Kind::Subprogram
|| kind
== Scope::Kind::MainProgram
;
6951 // base is a part-ref of a derived type; find the named component in its type.
6952 // Also handles intrinsic type parameter inquiries (%kind, %len) and
6953 // COMPLEX component references (%re, %im).
6954 const parser::Name
*DeclarationVisitor::FindComponent(
6955 const parser::Name
*base
, const parser::Name
&component
) {
6956 if (!base
|| !base
->symbol
) {
6959 if (auto *misc
{base
->symbol
->detailsIf
<MiscDetails
>()}) {
6960 if (component
.source
== "kind") {
6961 if (misc
->kind() == MiscDetails::Kind::ComplexPartRe
||
6962 misc
->kind() == MiscDetails::Kind::ComplexPartIm
||
6963 misc
->kind() == MiscDetails::Kind::KindParamInquiry
||
6964 misc
->kind() == MiscDetails::Kind::LenParamInquiry
) {
6965 // x%{re,im,kind,len}%kind
6966 MakePlaceholder(component
, MiscDetails::Kind::KindParamInquiry
);
6971 CheckEntryDummyUse(base
->source
, base
->symbol
);
6972 auto &symbol
{base
->symbol
->GetUltimate()};
6973 if (!symbol
.has
<AssocEntityDetails
>() && !ConvertToObjectEntity(symbol
)) {
6974 SayWithDecl(*base
, symbol
,
6975 "'%s' is an invalid base for a component reference"_err_en_US
);
6978 auto *type
{symbol
.GetType()};
6980 return nullptr; // should have already reported error
6982 if (const IntrinsicTypeSpec
* intrinsic
{type
->AsIntrinsic()}) {
6983 auto category
{intrinsic
->category()};
6984 MiscDetails::Kind miscKind
{MiscDetails::Kind::None
};
6985 if (component
.source
== "kind") {
6986 miscKind
= MiscDetails::Kind::KindParamInquiry
;
6987 } else if (category
== TypeCategory::Character
) {
6988 if (component
.source
== "len") {
6989 miscKind
= MiscDetails::Kind::LenParamInquiry
;
6991 } else if (category
== TypeCategory::Complex
) {
6992 if (component
.source
== "re") {
6993 miscKind
= MiscDetails::Kind::ComplexPartRe
;
6994 } else if (component
.source
== "im") {
6995 miscKind
= MiscDetails::Kind::ComplexPartIm
;
6998 if (miscKind
!= MiscDetails::Kind::None
) {
6999 MakePlaceholder(component
, miscKind
);
7002 } else if (DerivedTypeSpec
* derived
{type
->AsDerived()}) {
7003 derived
->Instantiate(currScope()); // in case of forward referenced type
7004 if (const Scope
* scope
{derived
->scope()}) {
7005 if (Resolve(component
, scope
->FindComponent(component
.source
))) {
7006 if (auto msg
{CheckAccessibleSymbol(currScope(), *component
.symbol
)}) {
7007 context().Say(component
.source
, *msg
);
7011 SayDerivedType(component
.source
,
7012 "Component '%s' not found in derived type '%s'"_err_en_US
, *scope
);
7017 if (symbol
.test(Symbol::Flag::Implicit
)) {
7019 "'%s' is not an object of derived type; it is implicitly typed"_err_en_US
);
7022 *base
, symbol
, "'%s' is not an object of derived type"_err_en_US
);
7027 void DeclarationVisitor::Initialization(const parser::Name
&name
,
7028 const parser::Initialization
&init
, bool inComponentDecl
) {
7029 // Traversal of the initializer was deferred to here so that the
7030 // symbol being declared can be available for use in the expression, e.g.:
7031 // real, parameter :: x = tiny(x)
7035 Symbol
&ultimate
{name
.symbol
->GetUltimate()};
7036 // TODO: check C762 - all bounds and type parameters of component
7037 // are colons or constant expressions if component is initialized
7040 [&](const parser::ConstantExpr
&expr
) {
7041 NonPointerInitialization(name
, expr
);
7043 [&](const parser::NullInit
&null
) { // => NULL()
7045 if (auto nullInit
{EvaluateExpr(null
)}) {
7046 if (!evaluate::IsNullPointer(*nullInit
)) { // C813
7047 Say(null
.v
.value().source
,
7048 "Pointer initializer must be intrinsic NULL()"_err_en_US
);
7049 } else if (IsPointer(ultimate
)) {
7050 if (auto *object
{ultimate
.detailsIf
<ObjectEntityDetails
>()}) {
7051 object
->set_init(std::move(*nullInit
));
7052 } else if (auto *procPtr
{
7053 ultimate
.detailsIf
<ProcEntityDetails
>()}) {
7054 procPtr
->set_init(nullptr);
7058 "Non-pointer component '%s' initialized with null pointer"_err_en_US
);
7062 [&](const parser::InitialDataTarget
&) {
7063 // Defer analysis to the end of the specification part
7064 // so that forward references and attribute checks like SAVE
7066 ultimate
.set(Symbol::Flag::InDataStmt
);
7068 [&](const std::list
<Indirection
<parser::DataStmtValue
>> &values
) {
7069 // Handled later in data-to-inits conversion
7070 ultimate
.set(Symbol::Flag::InDataStmt
);
7077 void DeclarationVisitor::PointerInitialization(
7078 const parser::Name
&name
, const parser::InitialDataTarget
&target
) {
7080 Symbol
&ultimate
{name
.symbol
->GetUltimate()};
7081 if (!context().HasError(ultimate
)) {
7082 if (IsPointer(ultimate
)) {
7083 if (auto *details
{ultimate
.detailsIf
<ObjectEntityDetails
>()}) {
7084 CHECK(!details
->init());
7086 if (MaybeExpr expr
{EvaluateExpr(target
)}) {
7087 // Validation is done in declaration checking.
7088 details
->set_init(std::move(*expr
));
7093 "'%s' is not a pointer but is initialized like one"_err_en_US
);
7094 context().SetError(ultimate
);
7099 void DeclarationVisitor::PointerInitialization(
7100 const parser::Name
&name
, const parser::ProcPointerInit
&target
) {
7102 Symbol
&ultimate
{name
.symbol
->GetUltimate()};
7103 if (!context().HasError(ultimate
)) {
7104 if (IsProcedurePointer(ultimate
)) {
7105 auto &details
{ultimate
.get
<ProcEntityDetails
>()};
7106 CHECK(!details
.init());
7107 if (const auto *targetName
{std::get_if
<parser::Name
>(&target
.u
)}) {
7109 if (!CheckUseError(*targetName
) && targetName
->symbol
) {
7110 // Validation is done in declaration checking.
7111 details
.set_init(*targetName
->symbol
);
7113 } else { // explicit NULL
7114 details
.set_init(nullptr);
7118 "'%s' is not a procedure pointer but is initialized "
7119 "like one"_err_en_US
);
7120 context().SetError(ultimate
);
7126 void DeclarationVisitor::NonPointerInitialization(
7127 const parser::Name
&name
, const parser::ConstantExpr
&expr
) {
7129 Symbol
&ultimate
{name
.symbol
->GetUltimate()};
7130 if (!context().HasError(ultimate
) && !context().HasError(name
.symbol
)) {
7131 if (IsPointer(ultimate
)) {
7133 "'%s' is a pointer but is not initialized like one"_err_en_US
);
7134 } else if (auto *details
{ultimate
.detailsIf
<ObjectEntityDetails
>()}) {
7135 CHECK(!details
->init());
7136 if (IsAllocatable(ultimate
)) {
7137 Say(name
, "Allocatable object '%s' cannot be initialized"_err_en_US
);
7141 if (ultimate
.owner().IsParameterizedDerivedType()) {
7142 // Save the expression for per-instantiation analysis.
7143 details
->set_unanalyzedPDTComponentInit(&expr
.thing
.value());
7145 if (MaybeExpr folded
{EvaluateNonPointerInitializer(
7146 ultimate
, expr
, expr
.thing
.value().source
)}) {
7147 details
->set_init(std::move(*folded
));
7151 Say(name
, "'%s' is not an object that can be initialized"_err_en_US
);
7157 void ResolveNamesVisitor::HandleCall(
7158 Symbol::Flag procFlag
, const parser::Call
&call
) {
7161 [&](const parser::Name
&x
) { HandleProcedureName(procFlag
, x
); },
7162 [&](const parser::ProcComponentRef
&x
) {
7164 const parser::Name
&name
{x
.v
.thing
.component
};
7165 if (Symbol
* symbol
{name
.symbol
}) {
7166 if (IsProcedure(*symbol
)) {
7167 SetProcFlag(name
, *symbol
, procFlag
);
7172 std::get
<parser::ProcedureDesignator
>(call
.t
).u
);
7173 Walk(std::get
<std::list
<parser::ActualArgSpec
>>(call
.t
));
7176 void ResolveNamesVisitor::HandleProcedureName(
7177 Symbol::Flag flag
, const parser::Name
&name
) {
7178 CHECK(flag
== Symbol::Flag::Function
|| flag
== Symbol::Flag::Subroutine
);
7179 auto *symbol
{FindSymbol(NonDerivedTypeScope(), name
)};
7181 if (IsIntrinsic(name
.source
, flag
)) {
7183 &MakeSymbol(InclusiveScope(), name
.source
, Attrs
{Attr::INTRINSIC
});
7184 } else if (const auto ppcBuiltinScope
=
7185 currScope().context().GetPPCBuiltinsScope()) {
7186 // Check if it is a builtin from the predefined module
7187 symbol
= FindSymbol(*ppcBuiltinScope
, name
);
7189 symbol
= &MakeSymbol(context().globalScope(), name
.source
, Attrs
{});
7191 symbol
= &MakeSymbol(context().globalScope(), name
.source
, Attrs
{});
7193 Resolve(name
, *symbol
);
7194 if (!symbol
->attrs().test(Attr::INTRINSIC
)) {
7195 if (CheckImplicitNoneExternal(name
.source
, *symbol
)) {
7196 MakeExternal(*symbol
);
7199 CheckEntryDummyUse(name
.source
, symbol
);
7200 ConvertToProcEntity(*symbol
);
7201 SetProcFlag(name
, *symbol
, flag
);
7202 } else if (CheckUseError(name
)) {
7203 // error was reported
7205 auto &nonUltimateSymbol
{*symbol
};
7206 symbol
= &Resolve(name
, symbol
)->GetUltimate();
7207 CheckEntryDummyUse(name
.source
, symbol
);
7208 bool convertedToProcEntity
{ConvertToProcEntity(*symbol
)};
7209 if (convertedToProcEntity
&& !symbol
->attrs().test(Attr::EXTERNAL
) &&
7210 IsIntrinsic(symbol
->name(), flag
) && !IsDummy(*symbol
)) {
7211 AcquireIntrinsicProcedureFlags(*symbol
);
7213 if (!SetProcFlag(name
, *symbol
, flag
)) {
7214 return; // reported error
7216 if (!symbol
->has
<GenericDetails
>()) {
7217 CheckImplicitNoneExternal(name
.source
, *symbol
);
7219 if (IsProcedure(*symbol
) || symbol
->has
<DerivedTypeDetails
>() ||
7220 symbol
->has
<AssocEntityDetails
>()) {
7221 // Symbols with DerivedTypeDetails and AssocEntityDetails are accepted
7222 // here as procedure-designators because this means the related
7223 // FunctionReference are mis-parsed structure constructors or array
7224 // references that will be fixed later when analyzing expressions.
7225 } else if (symbol
->has
<ObjectEntityDetails
>()) {
7226 // Symbols with ObjectEntityDetails are also accepted because this can be
7227 // a mis-parsed array references that will be fixed later. Ensure that if
7228 // this is a symbol from a host procedure, a symbol with HostAssocDetails
7229 // is created for the current scope.
7230 // Operate on non ultimate symbol so that HostAssocDetails are also
7231 // created for symbols used associated in the host procedure.
7232 if (IsUplevelReference(nonUltimateSymbol
)) {
7233 MakeHostAssocSymbol(name
, nonUltimateSymbol
);
7235 } else if (symbol
->test(Symbol::Flag::Implicit
)) {
7237 "Use of '%s' as a procedure conflicts with its implicit definition"_err_en_US
);
7239 SayWithDecl(name
, *symbol
,
7240 "Use of '%s' as a procedure conflicts with its declaration"_err_en_US
);
7245 bool ResolveNamesVisitor::CheckImplicitNoneExternal(
7246 const SourceName
&name
, const Symbol
&symbol
) {
7247 if (isImplicitNoneExternal() && !symbol
.attrs().test(Attr::EXTERNAL
) &&
7248 !symbol
.attrs().test(Attr::INTRINSIC
) && !symbol
.HasExplicitInterface()) {
7250 "'%s' is an external procedure without the EXTERNAL"
7251 " attribute in a scope with IMPLICIT NONE(EXTERNAL)"_err_en_US
);
7257 // Variant of HandleProcedureName() for use while skimming the executable
7258 // part of a subprogram to catch calls to dummy procedures that are part
7259 // of the subprogram's interface, and to mark as procedures any symbols
7260 // that might otherwise have been miscategorized as objects.
7261 void ResolveNamesVisitor::NoteExecutablePartCall(
7262 Symbol::Flag flag
, const parser::Call
&call
) {
7263 auto &designator
{std::get
<parser::ProcedureDesignator
>(call
.t
)};
7264 if (const auto *name
{std::get_if
<parser::Name
>(&designator
.u
)}) {
7265 // Subtlety: The symbol pointers in the parse tree are not set, because
7266 // they might end up resolving elsewhere (e.g., construct entities in
7268 if (Symbol
* symbol
{currScope().FindSymbol(name
->source
)}) {
7269 Symbol::Flag other
{flag
== Symbol::Flag::Subroutine
7270 ? Symbol::Flag::Function
7271 : Symbol::Flag::Subroutine
};
7272 if (!symbol
->test(other
)) {
7273 ConvertToProcEntity(*symbol
);
7274 if (symbol
->has
<ProcEntityDetails
>()) {
7276 if (IsDummy(*symbol
)) {
7277 SetImplicitAttr(*symbol
, Attr::EXTERNAL
);
7279 ApplyImplicitRules(*symbol
);
7286 static bool IsLocallyImplicitGlobalSymbol(
7287 const Symbol
&symbol
, const parser::Name
&localName
) {
7288 return symbol
.owner().IsGlobal() &&
7290 !symbol
.scope()->sourceRange().Contains(localName
.source
));
7293 static bool TypesMismatchIfNonNull(
7294 const DeclTypeSpec
*type1
, const DeclTypeSpec
*type2
) {
7295 return type1
&& type2
&& *type1
!= *type2
;
7298 // Check and set the Function or Subroutine flag on symbol; false on error.
7299 bool ResolveNamesVisitor::SetProcFlag(
7300 const parser::Name
&name
, Symbol
&symbol
, Symbol::Flag flag
) {
7301 if (symbol
.test(Symbol::Flag::Function
) && flag
== Symbol::Flag::Subroutine
) {
7303 name
, symbol
, "Cannot call function '%s' like a subroutine"_err_en_US
);
7305 } else if (symbol
.test(Symbol::Flag::Subroutine
) &&
7306 flag
== Symbol::Flag::Function
) {
7308 name
, symbol
, "Cannot call subroutine '%s' like a function"_err_en_US
);
7310 } else if (flag
== Symbol::Flag::Function
&&
7311 IsLocallyImplicitGlobalSymbol(symbol
, name
) &&
7312 TypesMismatchIfNonNull(symbol
.GetType(), GetImplicitType(symbol
))) {
7313 SayWithDecl(name
, symbol
,
7314 "Implicit declaration of function '%s' has a different result type than in previous declaration"_err_en_US
);
7316 } else if (symbol
.has
<ProcEntityDetails
>()) {
7317 symbol
.set(flag
); // in case it hasn't been set yet
7318 if (flag
== Symbol::Flag::Function
) {
7319 ApplyImplicitRules(symbol
);
7321 if (symbol
.attrs().test(Attr::INTRINSIC
)) {
7322 AcquireIntrinsicProcedureFlags(symbol
);
7324 } else if (symbol
.GetType() && flag
== Symbol::Flag::Subroutine
) {
7326 name
, symbol
, "Cannot call function '%s' like a subroutine"_err_en_US
);
7327 } else if (symbol
.attrs().test(Attr::INTRINSIC
)) {
7328 AcquireIntrinsicProcedureFlags(symbol
);
7333 bool ModuleVisitor::Pre(const parser::AccessStmt
&x
) {
7334 Attr accessAttr
{AccessSpecToAttr(std::get
<parser::AccessSpec
>(x
.t
))};
7335 if (!currScope().IsModule()) { // C869
7336 Say(currStmtSource().value(),
7337 "%s statement may only appear in the specification part of a module"_err_en_US
,
7338 EnumToString(accessAttr
));
7341 const auto &accessIds
{std::get
<std::list
<parser::AccessId
>>(x
.t
)};
7342 if (accessIds
.empty()) {
7343 if (prevAccessStmt_
) { // C869
7344 Say("The default accessibility of this module has already been declared"_err_en_US
)
7345 .Attach(*prevAccessStmt_
, "Previous declaration"_en_US
);
7347 prevAccessStmt_
= currStmtSource();
7348 defaultAccess_
= accessAttr
;
7350 for (const auto &accessId
: accessIds
) {
7351 GenericSpecInfo info
{accessId
.v
.value()};
7352 auto *symbol
{FindInScope(info
.symbolName())};
7353 if (!symbol
&& !info
.kind().IsName()) {
7354 symbol
= &MakeSymbol(info
.symbolName(), Attrs
{}, GenericDetails
{});
7356 info
.Resolve(&SetAccess(info
.symbolName(), accessAttr
, symbol
));
7362 // Set the access specification for this symbol.
7363 Symbol
&ModuleVisitor::SetAccess(
7364 const SourceName
&name
, Attr attr
, Symbol
*symbol
) {
7366 symbol
= &MakeSymbol(name
);
7368 Attrs
&attrs
{symbol
->attrs()};
7369 if (attrs
.HasAny({Attr::PUBLIC
, Attr::PRIVATE
})) {
7370 // PUBLIC/PRIVATE already set: make it a fatal error if it changed
7371 Attr prev
= attrs
.test(Attr::PUBLIC
) ? Attr::PUBLIC
: Attr::PRIVATE
;
7374 "The accessibility of '%s' has already been specified as %s"_warn_en_US
,
7375 attr
!= prev
? parser::Severity::Error
: parser::Severity::Warning
),
7376 MakeOpName(name
), EnumToString(prev
));
7383 static bool NeedsExplicitType(const Symbol
&symbol
) {
7384 if (symbol
.has
<UnknownDetails
>()) {
7386 } else if (const auto *details
{symbol
.detailsIf
<EntityDetails
>()}) {
7387 return !details
->type();
7388 } else if (const auto *details
{symbol
.detailsIf
<ObjectEntityDetails
>()}) {
7389 return !details
->type();
7390 } else if (const auto *details
{symbol
.detailsIf
<ProcEntityDetails
>()}) {
7391 return !details
->procInterface() && !details
->type();
7397 bool ResolveNamesVisitor::Pre(const parser::SpecificationPart
&x
) {
7398 const auto &[accDecls
, ompDecls
, compilerDirectives
, useStmts
, importStmts
,
7399 implicitPart
, decls
] = x
.t
;
7400 auto flagRestorer
{common::ScopedSet(inSpecificationPart_
, true)};
7402 common::ScopedSet(specPartState_
, SpecificationPartState
{})};
7405 Walk(compilerDirectives
);
7409 ClearExplicitIntrinsicUses();
7412 for (const auto &decl
: decls
) {
7413 if (const auto *spec
{
7414 std::get_if
<parser::SpecificationConstruct
>(&decl
.u
)}) {
7415 PreSpecificationConstruct(*spec
);
7419 FinishSpecificationPart(decls
);
7423 // Initial processing on specification constructs, before visiting them.
7424 void ResolveNamesVisitor::PreSpecificationConstruct(
7425 const parser::SpecificationConstruct
&spec
) {
7428 [&](const parser::Statement
<Indirection
<parser::GenericStmt
>> &y
) {
7429 CreateGeneric(std::get
<parser::GenericSpec
>(y
.statement
.value().t
));
7431 [&](const Indirection
<parser::InterfaceBlock
> &y
) {
7432 const auto &stmt
{std::get
<parser::Statement
<parser::InterfaceStmt
>>(
7434 if (const auto *spec
{parser::Unwrap
<parser::GenericSpec
>(stmt
)}) {
7435 CreateGeneric(*spec
);
7438 [&](const parser::Statement
<parser::OtherSpecificationStmt
> &y
) {
7439 if (const auto *commonStmt
{parser::Unwrap
<parser::CommonStmt
>(y
)}) {
7440 CreateCommonBlockSymbols(*commonStmt
);
7443 [&](const auto &) {},
7448 void ResolveNamesVisitor::CreateCommonBlockSymbols(
7449 const parser::CommonStmt
&commonStmt
) {
7450 for (const parser::CommonStmt::Block
&block
: commonStmt
.blocks
) {
7451 const auto &[name
, objects
] = block
.t
;
7452 Symbol
&commonBlock
{MakeCommonBlockSymbol(name
)};
7453 for (const auto &object
: objects
) {
7454 Symbol
&obj
{DeclareObjectEntity(std::get
<parser::Name
>(object
.t
))};
7455 if (auto *details
{obj
.detailsIf
<ObjectEntityDetails
>()}) {
7456 details
->set_commonBlock(commonBlock
);
7457 commonBlock
.get
<CommonBlockDetails
>().add_object(obj
);
7463 void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec
&x
) {
7464 auto info
{GenericSpecInfo
{x
}};
7465 SourceName symbolName
{info
.symbolName()};
7466 if (IsLogicalConstant(context(), symbolName
)) {
7468 "Logical constant '%s' may not be used as a defined operator"_err_en_US
);
7471 GenericDetails genericDetails
;
7472 Symbol
*existing
{nullptr};
7473 // Check all variants of names, e.g. "operator(.ne.)" for "operator(/=)"
7474 for (const std::string
&n
: GetAllNames(context(), symbolName
)) {
7475 existing
= currScope().FindSymbol(SourceName
{n
});
7481 Symbol
&ultimate
{existing
->GetUltimate()};
7482 if (auto *existingGeneric
{ultimate
.detailsIf
<GenericDetails
>()}) {
7483 if (&existing
->owner() == &currScope()) {
7484 if (const auto *existingUse
{existing
->detailsIf
<UseDetails
>()}) {
7485 // Create a local copy of a use associated generic so that
7486 // it can be locally extended without corrupting the original.
7487 genericDetails
.CopyFrom(*existingGeneric
);
7488 if (existingGeneric
->specific()) {
7489 genericDetails
.set_specific(*existingGeneric
->specific());
7492 genericDetails
, existing
->name(), existingUse
->symbol());
7493 } else if (existing
== &ultimate
) {
7494 // Extending an extant generic in the same scope
7495 info
.Resolve(existing
);
7498 // Host association of a generic is handled elsewhere
7499 CHECK(existing
->has
<HostAssocDetails
>());
7502 // Create a new generic for this scope.
7504 } else if (ultimate
.has
<SubprogramDetails
>() ||
7505 ultimate
.has
<SubprogramNameDetails
>()) {
7506 genericDetails
.set_specific(*existing
);
7507 } else if (ultimate
.has
<DerivedTypeDetails
>()) {
7508 genericDetails
.set_derivedType(*existing
);
7509 } else if (&existing
->owner() == &currScope()) {
7510 SayAlreadyDeclared(symbolName
, *existing
);
7513 if (&existing
->owner() == &currScope()) {
7514 EraseSymbol(*existing
);
7517 info
.Resolve(&MakeSymbol(symbolName
, Attrs
{}, std::move(genericDetails
)));
7520 void ResolveNamesVisitor::FinishSpecificationPart(
7521 const std::list
<parser::DeclarationConstruct
> &decls
) {
7522 badStmtFuncFound_
= false;
7523 funcResultStack().CompleteFunctionResultType();
7525 bool inModule
{currScope().kind() == Scope::Kind::Module
};
7526 for (auto &pair
: currScope()) {
7527 auto &symbol
{*pair
.second
};
7528 if (NeedsExplicitType(symbol
)) {
7529 ApplyImplicitRules(symbol
);
7531 if (IsDummy(symbol
) && isImplicitNoneType() &&
7532 symbol
.test(Symbol::Flag::Implicit
) && !context().HasError(symbol
)) {
7534 "No explicit type declared for dummy argument '%s'"_err_en_US
);
7535 context().SetError(symbol
);
7537 if (symbol
.has
<GenericDetails
>()) {
7538 CheckGenericProcedures(symbol
);
7540 if (inModule
&& symbol
.attrs().test(Attr::EXTERNAL
) &&
7541 !symbol
.test(Symbol::Flag::Function
) &&
7542 !symbol
.test(Symbol::Flag::Subroutine
)) {
7543 // in a module, external proc without return type is subroutine
7545 symbol
.GetType() ? Symbol::Flag::Function
: Symbol::Flag::Subroutine
);
7547 if (!symbol
.has
<HostAssocDetails
>()) {
7548 CheckPossibleBadForwardRef(symbol
);
7551 currScope().InstantiateDerivedTypes();
7552 for (const auto &decl
: decls
) {
7553 if (const auto *statement
{std::get_if
<
7554 parser::Statement
<common::Indirection
<parser::StmtFunctionStmt
>>>(
7556 AnalyzeStmtFunctionStmt(statement
->statement
.value());
7559 // TODO: what about instantiations in BLOCK?
7561 CheckCommonBlocks();
7562 if (!inInterfaceBlock()) {
7563 // TODO: warn for the case where the EQUIVALENCE statement is in a
7564 // procedure declaration in an interface block
7565 CheckEquivalenceSets();
7569 // Analyze the bodies of statement functions now that the symbols in this
7570 // specification part have been fully declared and implicitly typed.
7571 // (Statement function references are not allowed in specification
7572 // expressions, so it's safe to defer processing their definitions.)
7573 void ResolveNamesVisitor::AnalyzeStmtFunctionStmt(
7574 const parser::StmtFunctionStmt
&stmtFunc
) {
7575 const auto &name
{std::get
<parser::Name
>(stmtFunc
.t
)};
7576 Symbol
*symbol
{name
.symbol
};
7577 auto *details
{symbol
? symbol
->detailsIf
<SubprogramDetails
>() : nullptr};
7578 if (!details
|| !symbol
->scope()) {
7581 // Resolve the symbols on the RHS of the statement function.
7582 PushScope(*symbol
->scope());
7583 const auto &parsedExpr
{std::get
<parser::Scalar
<parser::Expr
>>(stmtFunc
.t
)};
7586 if (auto expr
{AnalyzeExpr(context(), stmtFunc
)}) {
7587 if (auto type
{evaluate::DynamicType::From(*symbol
)}) {
7588 if (auto converted
{evaluate::ConvertToType(*type
, std::move(*expr
))}) {
7589 details
->set_stmtFunction(std::move(*converted
));
7592 "Defining expression of statement function '%s' cannot be converted to its result type %s"_err_en_US
,
7593 name
.source
, type
->AsFortran());
7596 details
->set_stmtFunction(std::move(*expr
));
7599 if (!details
->stmtFunction()) {
7600 context().SetError(*symbol
);
7604 void ResolveNamesVisitor::CheckImports() {
7605 auto &scope
{currScope()};
7606 switch (scope
.GetImportKind()) {
7607 case common::ImportKind::None
:
7609 case common::ImportKind::All
:
7610 // C8102: all entities in host must not be hidden
7611 for (const auto &pair
: scope
.parent()) {
7612 auto &name
{pair
.first
};
7613 std::optional
<SourceName
> scopeName
{scope
.GetName()};
7614 if (!scopeName
|| name
!= *scopeName
) {
7615 CheckImport(prevImportStmt_
.value(), name
);
7619 case common::ImportKind::Default
:
7620 case common::ImportKind::Only
:
7621 // C8102: entities named in IMPORT must not be hidden
7622 for (auto &name
: scope
.importNames()) {
7623 CheckImport(name
, name
);
7629 void ResolveNamesVisitor::CheckImport(
7630 const SourceName
&location
, const SourceName
&name
) {
7631 if (auto *symbol
{FindInScope(name
)}) {
7632 const Symbol
&ultimate
{symbol
->GetUltimate()};
7633 if (&ultimate
.owner() == &currScope()) {
7634 Say(location
, "'%s' from host is not accessible"_err_en_US
, name
)
7635 .Attach(symbol
->name(), "'%s' is hidden by this entity"_en_US
,
7641 bool ResolveNamesVisitor::Pre(const parser::ImplicitStmt
&x
) {
7642 return CheckNotInBlock("IMPLICIT") && // C1107
7643 ImplicitRulesVisitor::Pre(x
);
7646 void ResolveNamesVisitor::Post(const parser::PointerObject
&x
) {
7647 common::visit(common::visitors
{
7648 [&](const parser::Name
&x
) { ResolveName(x
); },
7649 [&](const parser::StructureComponent
&x
) {
7650 ResolveStructureComponent(x
);
7655 void ResolveNamesVisitor::Post(const parser::AllocateObject
&x
) {
7656 common::visit(common::visitors
{
7657 [&](const parser::Name
&x
) { ResolveName(x
); },
7658 [&](const parser::StructureComponent
&x
) {
7659 ResolveStructureComponent(x
);
7665 bool ResolveNamesVisitor::Pre(const parser::PointerAssignmentStmt
&x
) {
7666 const auto &dataRef
{std::get
<parser::DataRef
>(x
.t
)};
7667 const auto &bounds
{std::get
<parser::PointerAssignmentStmt::Bounds
>(x
.t
)};
7668 const auto &expr
{std::get
<parser::Expr
>(x
.t
)};
7669 ResolveDataRef(dataRef
);
7671 // Resolve unrestricted specific intrinsic procedures as in "p => cos".
7672 if (const parser::Name
* name
{parser::Unwrap
<parser::Name
>(expr
)}) {
7673 if (NameIsKnownOrIntrinsic(*name
)) {
7674 // If the name is known because it is an object entity from a host
7675 // procedure, create a host associated symbol.
7676 if (Symbol
* symbol
{name
->symbol
}; symbol
&&
7677 symbol
->GetUltimate().has
<ObjectEntityDetails
>() &&
7678 IsUplevelReference(*symbol
)) {
7679 MakeHostAssocSymbol(*name
, *symbol
);
7687 void ResolveNamesVisitor::Post(const parser::Designator
&x
) {
7688 ResolveDesignator(x
);
7690 void ResolveNamesVisitor::Post(const parser::SubstringInquiry
&x
) {
7691 Walk(std::get
<parser::SubstringRange
>(x
.v
.t
).t
);
7692 ResolveDataRef(std::get
<parser::DataRef
>(x
.v
.t
));
7695 void ResolveNamesVisitor::Post(const parser::ProcComponentRef
&x
) {
7696 ResolveStructureComponent(x
.v
.thing
);
7698 void ResolveNamesVisitor::Post(const parser::TypeGuardStmt
&x
) {
7699 DeclTypeSpecVisitor::Post(x
);
7700 ConstructVisitor::Post(x
);
7702 bool ResolveNamesVisitor::Pre(const parser::StmtFunctionStmt
&x
) {
7703 if (HandleStmtFunction(x
)) {
7706 // This is an array element assignment: resolve names of indices
7707 const auto &names
{std::get
<std::list
<parser::Name
>>(x
.t
)};
7708 for (auto &name
: names
) {
7715 bool ResolveNamesVisitor::Pre(const parser::DefinedOpName
&x
) {
7716 const parser::Name
&name
{x
.v
};
7717 if (FindSymbol(name
)) {
7719 } else if (IsLogicalConstant(context(), name
.source
)) {
7721 "Logical constant '%s' may not be used as a defined operator"_err_en_US
);
7723 // Resolved later in expression semantics
7724 MakePlaceholder(name
, MiscDetails::Kind::TypeBoundDefinedOp
);
7729 void ResolveNamesVisitor::Post(const parser::AssignStmt
&x
) {
7730 if (auto *name
{ResolveName(std::get
<parser::Name
>(x
.t
))}) {
7731 CheckEntryDummyUse(name
->source
, name
->symbol
);
7732 ConvertToObjectEntity(DEREF(name
->symbol
));
7735 void ResolveNamesVisitor::Post(const parser::AssignedGotoStmt
&x
) {
7736 if (auto *name
{ResolveName(std::get
<parser::Name
>(x
.t
))}) {
7737 CheckEntryDummyUse(name
->source
, name
->symbol
);
7738 ConvertToObjectEntity(DEREF(name
->symbol
));
7742 bool ResolveNamesVisitor::Pre(const parser::ProgramUnit
&x
) {
7743 if (std::holds_alternative
<common::Indirection
<parser::CompilerDirective
>>(
7745 // TODO: global directives
7748 auto root
{ProgramTree::Build(x
)};
7749 SetScope(topScope_
);
7750 ResolveSpecificationParts(root
);
7751 FinishSpecificationParts(root
);
7752 ResolveExecutionParts(root
);
7753 ResolveAccParts(context(), x
);
7754 ResolveOmpParts(context(), x
);
7758 template <typename A
> std::set
<SourceName
> GetUses(const A
&x
) {
7759 std::set
<SourceName
> uses
;
7760 if constexpr (!std::is_same_v
<A
, parser::CompilerDirective
>) {
7761 const auto &spec
{std::get
<parser::SpecificationPart
>(x
.t
)};
7762 const auto &unitUses
{std::get
<
7763 std::list
<parser::Statement
<common::Indirection
<parser::UseStmt
>>>>(
7765 for (const auto &u
: unitUses
) {
7766 uses
.insert(u
.statement
.value().moduleName
.source
);
7772 bool ResolveNamesVisitor::Pre(const parser::Program
&x
) {
7773 std::map
<SourceName
, const parser::ProgramUnit
*> modules
;
7774 std::set
<SourceName
> uses
;
7775 bool disordered
{false};
7776 for (const auto &progUnit
: x
.v
) {
7777 if (const auto *indMod
{
7778 std::get_if
<common::Indirection
<parser::Module
>>(&progUnit
.u
)}) {
7779 const parser::Module
&mod
{indMod
->value()};
7780 const auto &moduleStmt
{
7781 std::get
<parser::Statement
<parser::ModuleStmt
>>(mod
.t
)};
7782 const SourceName
&name
{moduleStmt
.statement
.v
.source
};
7783 if (auto iter
{modules
.find(name
)}; iter
!= modules
.end()) {
7785 "Module '%s' appears multiple times in a compilation unit"_err_en_US
)
7786 .Attach(iter
->first
, "First definition of module"_en_US
);
7789 modules
.emplace(name
, &progUnit
);
7790 if (auto iter
{uses
.find(name
)}; iter
!= uses
.end()) {
7792 "A USE statement referencing module '%s' appears earlier in this compilation unit"_port_en_US
)
7793 .Attach(*iter
, "First USE of module"_en_US
);
7797 for (SourceName used
: common::visit(
7798 [](const auto &indUnit
) { return GetUses(indUnit
.value()); },
7806 // Process modules in topological order
7807 std::vector
<const parser::ProgramUnit
*> moduleOrder
;
7808 while (!modules
.empty()) {
7810 for (const auto &pair
: modules
) {
7811 const SourceName
&name
{pair
.first
};
7812 const parser::ProgramUnit
&progUnit
{*pair
.second
};
7813 const parser::Module
&m
{
7814 std::get
<common::Indirection
<parser::Module
>>(progUnit
.u
).value()};
7816 for (const SourceName
&use
: GetUses(m
)) {
7817 if (modules
.find(use
) != modules
.end()) {
7823 moduleOrder
.push_back(&progUnit
);
7824 modules
.erase(name
);
7829 parser::Message
*msg
{nullptr};
7830 for (const auto &pair
: modules
) {
7832 msg
->Attach(pair
.first
, "Module in a cycle"_en_US
);
7834 msg
= &Say(pair
.first
,
7835 "Some modules in this compilation unit form one or more cycles of dependence"_err_en_US
);
7841 // Modules can be ordered. Process them first, and then all of the other
7843 for (const parser::ProgramUnit
*progUnit
: moduleOrder
) {
7846 for (const auto &progUnit
: x
.v
) {
7847 if (!std::get_if
<common::Indirection
<parser::Module
>>(&progUnit
.u
)) {
7854 // References to procedures need to record that their symbols are known
7855 // to be procedures, so that they don't get converted to objects by default.
7856 class ExecutionPartSkimmer
{
7858 explicit ExecutionPartSkimmer(ResolveNamesVisitor
&resolver
)
7859 : resolver_
{resolver
} {}
7861 void Walk(const parser::ExecutionPart
*exec
) {
7863 parser::Walk(*exec
, *this);
7867 template <typename A
> bool Pre(const A
&) { return true; }
7868 template <typename A
> void Post(const A
&) {}
7869 void Post(const parser::FunctionReference
&fr
) {
7870 resolver_
.NoteExecutablePartCall(Symbol::Flag::Function
, fr
.v
);
7872 void Post(const parser::CallStmt
&cs
) {
7873 resolver_
.NoteExecutablePartCall(Symbol::Flag::Subroutine
, cs
.v
);
7877 ResolveNamesVisitor
&resolver_
;
7880 // Build the scope tree and resolve names in the specification parts of this
7881 // node and its children
7882 void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree
&node
) {
7883 if (node
.isSpecificationPartResolved()) {
7884 return; // been here already
7886 node
.set_isSpecificationPartResolved();
7887 if (!BeginScopeForNode(node
)) {
7888 return; // an error prevented scope from being created
7890 Scope
&scope
{currScope()};
7891 node
.set_scope(scope
);
7894 [&](const auto *x
) {
7901 // If this is a function, convert result to an object. This is to prevent the
7902 // result from being converted later to a function symbol if it is called
7903 // inside the function.
7904 // If the result is function pointer, then ConvertToObjectEntity will not
7905 // convert the result to an object, and calling the symbol inside the function
7906 // will result in calls to the result pointer.
7907 // A function cannot be called recursively if RESULT was not used to define a
7908 // distinct result name (15.6.2.2 point 4.).
7909 if (Symbol
* symbol
{scope
.symbol()}) {
7910 if (auto *details
{symbol
->detailsIf
<SubprogramDetails
>()}) {
7911 if (details
->isFunction()) {
7912 ConvertToObjectEntity(const_cast<Symbol
&>(details
->result()));
7916 if (node
.IsModule()) {
7917 ApplyDefaultAccess();
7919 for (auto &child
: node
.children()) {
7920 ResolveSpecificationParts(child
);
7922 ExecutionPartSkimmer
{*this}.Walk(node
.exec());
7923 EndScopeForNode(node
);
7924 // Ensure that every object entity has a type.
7925 for (auto &pair
: *node
.scope()) {
7926 ApplyImplicitRules(*pair
.second
);
7930 // Add SubprogramNameDetails symbols for module and internal subprograms and
7931 // their ENTRY statements.
7932 void ResolveNamesVisitor::AddSubpNames(ProgramTree
&node
) {
7934 node
.IsModule() ? SubprogramKind::Module
: SubprogramKind::Internal
};
7935 for (auto &child
: node
.children()) {
7936 auto &symbol
{MakeSymbol(child
.name(), SubprogramNameDetails
{kind
, child
})};
7937 if (child
.HasModulePrefix()) {
7938 SetExplicitAttr(symbol
, Attr::MODULE
);
7940 auto childKind
{child
.GetKind()};
7941 if (childKind
== ProgramTree::Kind::Function
) {
7942 symbol
.set(Symbol::Flag::Function
);
7943 } else if (childKind
== ProgramTree::Kind::Subroutine
) {
7944 symbol
.set(Symbol::Flag::Subroutine
);
7946 continue; // make ENTRY symbols only where valid
7948 for (const auto &entryStmt
: child
.entryStmts()) {
7949 SubprogramNameDetails details
{kind
, child
};
7951 MakeSymbol(std::get
<parser::Name
>(entryStmt
->t
), std::move(details
))};
7952 symbol
.set(child
.GetSubpFlag());
7953 if (child
.HasModulePrefix()) {
7954 SetExplicitAttr(symbol
, Attr::MODULE
);
7958 for (const auto &generic
: node
.genericSpecs()) {
7959 if (const auto *name
{std::get_if
<parser::Name
>(&generic
->u
)}) {
7960 if (currScope().find(name
->source
) != currScope().end()) {
7961 // If this scope has both a generic interface and a contained
7962 // subprogram with the same name, create the generic's symbol
7963 // now so that any other generics of the same name that are pulled
7964 // into scope later via USE association will properly merge instead
7965 // of raising a bogus error due a conflict with the subprogram.
7966 CreateGeneric(*generic
);
7972 // Push a new scope for this node or return false on error.
7973 bool ResolveNamesVisitor::BeginScopeForNode(const ProgramTree
&node
) {
7974 switch (node
.GetKind()) {
7975 SWITCH_COVERS_ALL_CASES
7976 case ProgramTree::Kind::Program
:
7977 PushScope(Scope::Kind::MainProgram
,
7978 &MakeSymbol(node
.name(), MainProgramDetails
{}));
7980 case ProgramTree::Kind::Function
:
7981 case ProgramTree::Kind::Subroutine
:
7982 return BeginSubprogram(node
.name(), node
.GetSubpFlag(),
7983 node
.HasModulePrefix(), node
.bindingSpec(), &node
.entryStmts());
7984 case ProgramTree::Kind::MpSubprogram
:
7985 return BeginMpSubprogram(node
.name());
7986 case ProgramTree::Kind::Module
:
7987 BeginModule(node
.name(), false);
7989 case ProgramTree::Kind::Submodule
:
7990 return BeginSubmodule(node
.name(), node
.GetParentId());
7991 case ProgramTree::Kind::BlockData
:
7992 PushBlockDataScope(node
.name());
7997 void ResolveNamesVisitor::EndScopeForNode(const ProgramTree
&node
) {
7998 std::optional
<parser::CharBlock
> stmtSource
;
7999 const std::optional
<parser::LanguageBindingSpec
> *binding
{nullptr};
8002 [&](const parser::Statement
<parser::FunctionStmt
> *stmt
) {
8004 stmtSource
= stmt
->source
;
8005 if (const auto &maybeSuffix
{
8006 std::get
<std::optional
<parser::Suffix
>>(
8007 stmt
->statement
.t
)}) {
8008 binding
= &maybeSuffix
->binding
;
8012 [&](const parser::Statement
<parser::SubroutineStmt
> *stmt
) {
8014 stmtSource
= stmt
->source
;
8015 binding
= &std::get
<std::optional
<parser::LanguageBindingSpec
>>(
8019 [](const auto *) {},
8022 EndSubprogram(stmtSource
, binding
, &node
.entryStmts());
8025 // Some analyses and checks, such as the processing of initializers of
8026 // pointers, are deferred until all of the pertinent specification parts
8027 // have been visited. This deferred processing enables the use of forward
8028 // references in these circumstances.
8029 class DeferredCheckVisitor
{
8031 explicit DeferredCheckVisitor(ResolveNamesVisitor
&resolver
)
8032 : resolver_
{resolver
} {}
8034 template <typename A
> void Walk(const A
&x
) { parser::Walk(x
, *this); }
8036 template <typename A
> bool Pre(const A
&) { return true; }
8037 template <typename A
> void Post(const A
&) {}
8039 void Post(const parser::DerivedTypeStmt
&x
) {
8040 const auto &name
{std::get
<parser::Name
>(x
.t
)};
8041 if (Symbol
* symbol
{name
.symbol
}) {
8042 if (Scope
* scope
{symbol
->scope()}) {
8043 if (scope
->IsDerivedType()) {
8044 resolver_
.PushScope(*scope
);
8045 pushedScope_
= true;
8050 void Post(const parser::EndTypeStmt
&) {
8052 resolver_
.PopScope();
8053 pushedScope_
= false;
8057 void Post(const parser::ProcInterface
&pi
) {
8058 if (const auto *name
{std::get_if
<parser::Name
>(&pi
.u
)}) {
8059 resolver_
.CheckExplicitInterface(*name
);
8062 bool Pre(const parser::EntityDecl
&decl
) {
8063 Init(std::get
<parser::Name
>(decl
.t
),
8064 std::get
<std::optional
<parser::Initialization
>>(decl
.t
));
8067 bool Pre(const parser::ComponentDecl
&decl
) {
8068 Init(std::get
<parser::Name
>(decl
.t
),
8069 std::get
<std::optional
<parser::Initialization
>>(decl
.t
));
8072 bool Pre(const parser::ProcDecl
&decl
) {
8073 if (const auto &init
{
8074 std::get
<std::optional
<parser::ProcPointerInit
>>(decl
.t
)}) {
8075 resolver_
.PointerInitialization(std::get
<parser::Name
>(decl
.t
), *init
);
8079 void Post(const parser::TypeBoundProcedureStmt::WithInterface
&tbps
) {
8080 resolver_
.CheckExplicitInterface(tbps
.interfaceName
);
8082 void Post(const parser::TypeBoundProcedureStmt::WithoutInterface
&tbps
) {
8084 resolver_
.CheckBindings(tbps
);
8087 bool Pre(const parser::StmtFunctionStmt
&stmtFunc
) { return false; }
8090 void Init(const parser::Name
&name
,
8091 const std::optional
<parser::Initialization
> &init
) {
8093 if (const auto *target
{
8094 std::get_if
<parser::InitialDataTarget
>(&init
->u
)}) {
8095 resolver_
.PointerInitialization(name
, *target
);
8100 ResolveNamesVisitor
&resolver_
;
8101 bool pushedScope_
{false};
8104 // Perform checks and completions that need to happen after all of
8105 // the specification parts but before any of the execution parts.
8106 void ResolveNamesVisitor::FinishSpecificationParts(const ProgramTree
&node
) {
8107 if (!node
.scope()) {
8108 return; // error occurred creating scope
8110 SetScope(*node
.scope());
8111 // The initializers of pointers, the default initializers of pointer
8112 // components, non-deferred type-bound procedure bindings have not
8113 // yet been traversed.
8114 // We do that now, when any (formerly) forward references that appear
8115 // in those initializers will resolve to the right symbols without
8116 // incurring spurious errors with IMPLICIT NONE.
8117 DeferredCheckVisitor
{*this}.Walk(node
.spec());
8118 DeferredCheckVisitor
{*this}.Walk(node
.exec()); // for BLOCK
8119 for (Scope
&childScope
: currScope().children()) {
8120 if (childScope
.IsParameterizedDerivedTypeInstantiation()) {
8121 FinishDerivedTypeInstantiation(childScope
);
8124 for (const auto &child
: node
.children()) {
8125 FinishSpecificationParts(child
);
8129 // Duplicate and fold component object pointer default initializer designators
8130 // using the actual type parameter values of each particular instantiation.
8131 // Validation is done later in declaration checking.
8132 void ResolveNamesVisitor::FinishDerivedTypeInstantiation(Scope
&scope
) {
8133 CHECK(scope
.IsDerivedType() && !scope
.symbol());
8134 if (DerivedTypeSpec
* spec
{scope
.derivedTypeSpec()}) {
8135 spec
->Instantiate(currScope());
8136 const Symbol
&origTypeSymbol
{spec
->typeSymbol()};
8137 if (const Scope
* origTypeScope
{origTypeSymbol
.scope()}) {
8138 CHECK(origTypeScope
->IsDerivedType() &&
8139 origTypeScope
->symbol() == &origTypeSymbol
);
8140 auto &foldingContext
{GetFoldingContext()};
8141 auto restorer
{foldingContext
.WithPDTInstance(*spec
)};
8142 for (auto &pair
: scope
) {
8143 Symbol
&comp
{*pair
.second
};
8144 const Symbol
&origComp
{DEREF(FindInScope(*origTypeScope
, comp
.name()))};
8145 if (IsPointer(comp
)) {
8146 if (auto *details
{comp
.detailsIf
<ObjectEntityDetails
>()}) {
8147 auto origDetails
{origComp
.get
<ObjectEntityDetails
>()};
8148 if (const MaybeExpr
& init
{origDetails
.init()}) {
8149 SomeExpr newInit
{*init
};
8151 evaluate::Fold(foldingContext
, std::move(newInit
))};
8152 details
->set_init(std::move(folded
));
8161 // Resolve names in the execution part of this node and its children
8162 void ResolveNamesVisitor::ResolveExecutionParts(const ProgramTree
&node
) {
8163 if (!node
.scope()) {
8164 return; // error occurred creating scope
8166 SetScope(*node
.scope());
8167 if (const auto *exec
{node
.exec()}) {
8171 PopScope(); // converts unclassified entities into objects
8172 for (const auto &child
: node
.children()) {
8173 ResolveExecutionParts(child
);
8177 void ResolveNamesVisitor::Post(const parser::Program
&) {
8178 // ensure that all temps were deallocated
8180 CHECK(!GetDeclTypeSpec());
8183 // A singleton instance of the scope -> IMPLICIT rules mapping is
8184 // shared by all instances of ResolveNamesVisitor and accessed by this
8185 // pointer when the visitors (other than the top-level original) are
8187 static ImplicitRulesMap
*sharedImplicitRulesMap
{nullptr};
8190 SemanticsContext
&context
, const parser::Program
&program
, Scope
&top
) {
8191 ImplicitRulesMap implicitRulesMap
;
8192 auto restorer
{common::ScopedSet(sharedImplicitRulesMap
, &implicitRulesMap
)};
8193 ResolveNamesVisitor
{context
, implicitRulesMap
, top
}.Walk(program
);
8194 return !context
.AnyFatalError();
8197 // Processes a module (but not internal) function when it is referenced
8198 // in a specification expression in a sibling procedure.
8199 void ResolveSpecificationParts(
8200 SemanticsContext
&context
, const Symbol
&subprogram
) {
8201 auto originalLocation
{context
.location()};
8202 ImplicitRulesMap implicitRulesMap
;
8203 bool localImplicitRulesMap
{false};
8204 if (!sharedImplicitRulesMap
) {
8205 sharedImplicitRulesMap
= &implicitRulesMap
;
8206 localImplicitRulesMap
= true;
8208 ResolveNamesVisitor visitor
{
8209 context
, *sharedImplicitRulesMap
, context
.globalScope()};
8210 const auto &details
{subprogram
.get
<SubprogramNameDetails
>()};
8211 ProgramTree
&node
{details
.node()};
8212 const Scope
&moduleScope
{subprogram
.owner()};
8213 if (localImplicitRulesMap
) {
8214 visitor
.BeginScope(const_cast<Scope
&>(moduleScope
));
8216 visitor
.SetScope(const_cast<Scope
&>(moduleScope
));
8218 visitor
.ResolveSpecificationParts(node
);
8219 context
.set_location(std::move(originalLocation
));
8220 if (localImplicitRulesMap
) {
8221 sharedImplicitRulesMap
= nullptr;
8225 } // namespace Fortran::semantics