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 "resolve-directives.h"
14 #include "resolve-names-utils.h"
15 #include "rewrite-parse-tree.h"
16 #include "flang/Common/Fortran.h"
17 #include "flang/Common/default-kinds.h"
18 #include "flang/Common/indirection.h"
19 #include "flang/Common/restorer.h"
20 #include "flang/Common/visit.h"
21 #include "flang/Evaluate/characteristics.h"
22 #include "flang/Evaluate/check-expression.h"
23 #include "flang/Evaluate/common.h"
24 #include "flang/Evaluate/fold-designator.h"
25 #include "flang/Evaluate/fold.h"
26 #include "flang/Evaluate/intrinsics.h"
27 #include "flang/Evaluate/tools.h"
28 #include "flang/Evaluate/type.h"
29 #include "flang/Parser/parse-tree-visitor.h"
30 #include "flang/Parser/parse-tree.h"
31 #include "flang/Parser/tools.h"
32 #include "flang/Semantics/attr.h"
33 #include "flang/Semantics/expression.h"
34 #include "flang/Semantics/openmp-modifiers.h"
35 #include "flang/Semantics/program-tree.h"
36 #include "flang/Semantics/scope.h"
37 #include "flang/Semantics/semantics.h"
38 #include "flang/Semantics/symbol.h"
39 #include "flang/Semantics/tools.h"
40 #include "flang/Semantics/type.h"
41 #include "llvm/Support/raw_ostream.h"
47 namespace Fortran::semantics
{
49 using namespace parser::literals
;
51 template <typename T
> using Indirection
= common::Indirection
<T
>;
52 using Message
= parser::Message
;
53 using Messages
= parser::Messages
;
54 using MessageFixedText
= parser::MessageFixedText
;
55 using MessageFormattedText
= parser::MessageFormattedText
;
57 class ResolveNamesVisitor
;
60 // ImplicitRules maps initial character of identifier to the DeclTypeSpec
61 // representing the implicit type; std::nullopt if none.
62 // It also records the presence of IMPLICIT NONE statements.
63 // When inheritFromParent is set, defaults come from the parent rules.
66 ImplicitRules(SemanticsContext
&context
, const ImplicitRules
*parent
)
67 : parent_
{parent
}, context_
{context
},
68 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 const 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 // | + GenericHandler -------+ | |
141 // | | + InterfaceVisitor | | |
142 // | +-+ SubprogramVisitor ==|==+ | |
143 // + ArraySpecVisitor | | | |
144 // + DeclarationVisitor <--------+ | | |
145 // + ConstructVisitor | | |
146 // + ResolveNamesVisitor <------+-+-+
150 BaseVisitor() { DIE("BaseVisitor: default-constructed"); }
152 SemanticsContext
&c
, ResolveNamesVisitor
&v
, ImplicitRulesMap
&rules
)
153 : implicitRulesMap_
{&rules
}, this_
{&v
}, context_
{&c
}, messageHandler_
{c
} {
155 template <typename T
> void Walk(const T
&);
157 MessageHandler
&messageHandler() { return messageHandler_
; }
158 const std::optional
<SourceName
> &currStmtSource() {
159 return context_
->location();
161 SemanticsContext
&context() const { return *context_
; }
162 evaluate::FoldingContext
&GetFoldingContext() const {
163 return context_
->foldingContext();
166 const SourceName
&name
, std::optional
<Symbol::Flag
> flag
) const {
168 return context_
->intrinsics().IsIntrinsic(name
.ToString());
169 } else if (flag
== Symbol::Flag::Function
) {
170 return context_
->intrinsics().IsIntrinsicFunction(name
.ToString());
171 } else if (flag
== Symbol::Flag::Subroutine
) {
172 return context_
->intrinsics().IsIntrinsicSubroutine(name
.ToString());
174 DIE("expected Subroutine or Function flag");
178 bool InModuleFile() const {
179 return GetFoldingContext().moduleFileName().has_value();
182 // Make a placeholder symbol for a Name that otherwise wouldn't have one.
183 // It is not in any scope and always has MiscDetails.
184 void MakePlaceholder(const parser::Name
&, MiscDetails::Kind
);
186 template <typename T
> common::IfNoLvalue
<T
, T
> FoldExpr(T
&&expr
) {
187 return evaluate::Fold(GetFoldingContext(), std::move(expr
));
190 template <typename T
> MaybeExpr
EvaluateExpr(const T
&expr
) {
191 return FoldExpr(AnalyzeExpr(*context_
, expr
));
194 template <typename T
>
195 MaybeExpr
EvaluateNonPointerInitializer(
196 const Symbol
&symbol
, const T
&expr
, parser::CharBlock source
) {
197 if (!context().HasError(symbol
)) {
198 if (auto maybeExpr
{AnalyzeExpr(*context_
, expr
)}) {
199 auto restorer
{GetFoldingContext().messages().SetLocation(source
)};
200 return evaluate::NonPointerInitializationExpr(
201 symbol
, std::move(*maybeExpr
), GetFoldingContext());
207 template <typename T
> MaybeIntExpr
EvaluateIntExpr(const T
&expr
) {
208 return semantics::EvaluateIntExpr(*context_
, expr
);
211 template <typename T
>
212 MaybeSubscriptIntExpr
EvaluateSubscriptIntExpr(const T
&expr
) {
213 if (MaybeIntExpr maybeIntExpr
{EvaluateIntExpr(expr
)}) {
214 return FoldExpr(evaluate::ConvertToType
<evaluate::SubscriptInteger
>(
215 std::move(*maybeIntExpr
)));
221 template <typename
... A
> Message
&Say(A
&&...args
) {
222 return messageHandler_
.Say(std::forward
<A
>(args
)...);
224 template <typename
... A
>
226 const parser::Name
&name
, MessageFixedText
&&text
, const A
&...args
) {
227 return messageHandler_
.Say(name
.source
, std::move(text
), args
...);
231 ImplicitRulesMap
*implicitRulesMap_
{nullptr};
234 ResolveNamesVisitor
*this_
;
235 SemanticsContext
*context_
;
236 MessageHandler messageHandler_
;
239 // Provide Post methods to collect attributes into a member variable.
240 class AttrsVisitor
: public virtual BaseVisitor
{
242 bool BeginAttrs(); // always returns true
244 std::optional
<common::CUDADataAttr
> cudaDataAttr() { return cudaDataAttr_
; }
246 bool SetPassNameOn(Symbol
&);
247 void SetBindNameOn(Symbol
&);
248 void Post(const parser::LanguageBindingSpec
&);
249 bool Pre(const parser::IntentSpec
&);
250 bool Pre(const parser::Pass
&);
252 bool CheckAndSet(Attr
);
254 // Simple case: encountering CLASSNAME causes ATTRNAME to be set.
255 #define HANDLE_ATTR_CLASS(CLASSNAME, ATTRNAME) \
256 bool Pre(const parser::CLASSNAME &) { \
257 CheckAndSet(Attr::ATTRNAME); \
260 HANDLE_ATTR_CLASS(PrefixSpec::Elemental
, ELEMENTAL
)
261 HANDLE_ATTR_CLASS(PrefixSpec::Impure
, IMPURE
)
262 HANDLE_ATTR_CLASS(PrefixSpec::Module
, MODULE
)
263 HANDLE_ATTR_CLASS(PrefixSpec::Non_Recursive
, NON_RECURSIVE
)
264 HANDLE_ATTR_CLASS(PrefixSpec::Pure
, PURE
)
265 HANDLE_ATTR_CLASS(PrefixSpec::Recursive
, RECURSIVE
)
266 HANDLE_ATTR_CLASS(TypeAttrSpec::BindC
, BIND_C
)
267 HANDLE_ATTR_CLASS(BindAttr::Deferred
, DEFERRED
)
268 HANDLE_ATTR_CLASS(BindAttr::Non_Overridable
, NON_OVERRIDABLE
)
269 HANDLE_ATTR_CLASS(Abstract
, ABSTRACT
)
270 HANDLE_ATTR_CLASS(Allocatable
, ALLOCATABLE
)
271 HANDLE_ATTR_CLASS(Asynchronous
, ASYNCHRONOUS
)
272 HANDLE_ATTR_CLASS(Contiguous
, CONTIGUOUS
)
273 HANDLE_ATTR_CLASS(External
, EXTERNAL
)
274 HANDLE_ATTR_CLASS(Intrinsic
, INTRINSIC
)
275 HANDLE_ATTR_CLASS(NoPass
, NOPASS
)
276 HANDLE_ATTR_CLASS(Optional
, OPTIONAL
)
277 HANDLE_ATTR_CLASS(Parameter
, PARAMETER
)
278 HANDLE_ATTR_CLASS(Pointer
, POINTER
)
279 HANDLE_ATTR_CLASS(Protected
, PROTECTED
)
280 HANDLE_ATTR_CLASS(Save
, SAVE
)
281 HANDLE_ATTR_CLASS(Target
, TARGET
)
282 HANDLE_ATTR_CLASS(Value
, VALUE
)
283 HANDLE_ATTR_CLASS(Volatile
, VOLATILE
)
284 #undef HANDLE_ATTR_CLASS
285 bool Pre(const common::CUDADataAttr
);
288 std::optional
<Attrs
> attrs_
;
289 std::optional
<common::CUDADataAttr
> cudaDataAttr_
;
291 Attr
AccessSpecToAttr(const parser::AccessSpec
&x
) {
293 case parser::AccessSpec::Kind::Public
:
295 case parser::AccessSpec::Kind::Private
:
296 return Attr::PRIVATE
;
298 llvm_unreachable("Switch covers all cases"); // suppress g++ warning
300 Attr
IntentSpecToAttr(const parser::IntentSpec
&x
) {
302 case parser::IntentSpec::Intent::In
:
303 return Attr::INTENT_IN
;
304 case parser::IntentSpec::Intent::Out
:
305 return Attr::INTENT_OUT
;
306 case parser::IntentSpec::Intent::InOut
:
307 return Attr::INTENT_INOUT
;
309 llvm_unreachable("Switch covers all cases"); // suppress g++ warning
313 bool IsDuplicateAttr(Attr
);
314 bool HaveAttrConflict(Attr
, Attr
, Attr
);
315 bool IsConflictingAttr(Attr
);
317 MaybeExpr bindName_
; // from BIND(C, NAME="...")
318 bool isCDefined_
{false}; // BIND(C, NAME="...", CDEFINED) extension
319 std::optional
<SourceName
> passName_
; // from PASS(...)
322 // Find and create types from declaration-type-spec nodes.
323 class DeclTypeSpecVisitor
: public AttrsVisitor
{
325 using AttrsVisitor::Post
;
326 using AttrsVisitor::Pre
;
327 void Post(const parser::IntrinsicTypeSpec::DoublePrecision
&);
328 void Post(const parser::IntrinsicTypeSpec::DoubleComplex
&);
329 void Post(const parser::DeclarationTypeSpec::ClassStar
&);
330 void Post(const parser::DeclarationTypeSpec::TypeStar
&);
331 bool Pre(const parser::TypeGuardStmt
&);
332 void Post(const parser::TypeGuardStmt
&);
333 void Post(const parser::TypeSpec
&);
335 // Walk the parse tree of a type spec and return the DeclTypeSpec for it.
336 template <typename T
>
337 const DeclTypeSpec
*ProcessTypeSpec(const T
&x
, bool allowForward
= false) {
338 auto restorer
{common::ScopedSet(state_
, State
{})};
339 set_allowForwardReferenceToDerivedType(allowForward
);
342 const auto *type
{GetDeclTypeSpec()};
349 bool expectDeclTypeSpec
{false}; // should see decl-type-spec only when true
350 const DeclTypeSpec
*declTypeSpec
{nullptr};
352 DerivedTypeSpec
*type
{nullptr};
353 DeclTypeSpec::Category category
{DeclTypeSpec::TypeDerived
};
355 bool allowForwardReferenceToDerivedType
{false};
358 bool allowForwardReferenceToDerivedType() const {
359 return state_
.allowForwardReferenceToDerivedType
;
361 void set_allowForwardReferenceToDerivedType(bool yes
) {
362 state_
.allowForwardReferenceToDerivedType
= yes
;
365 const DeclTypeSpec
*GetDeclTypeSpec();
366 void BeginDeclTypeSpec();
367 void EndDeclTypeSpec();
368 void SetDeclTypeSpec(const DeclTypeSpec
&);
369 void SetDeclTypeSpecCategory(DeclTypeSpec::Category
);
370 DeclTypeSpec::Category
GetDeclTypeSpecCategory() const {
371 return state_
.derived
.category
;
373 KindExpr
GetKindParamExpr(
374 TypeCategory
, const std::optional
<parser::KindSelector
> &);
375 void CheckForAbstractType(const Symbol
&typeSymbol
);
380 void MakeNumericType(TypeCategory
, int kind
);
383 // Visit ImplicitStmt and related parse tree nodes and updates implicit rules.
384 class ImplicitRulesVisitor
: public DeclTypeSpecVisitor
{
386 using DeclTypeSpecVisitor::Post
;
387 using DeclTypeSpecVisitor::Pre
;
388 using ImplicitNoneNameSpec
= parser::ImplicitStmt::ImplicitNoneNameSpec
;
390 void Post(const parser::ParameterStmt
&);
391 bool Pre(const parser::ImplicitStmt
&);
392 bool Pre(const parser::LetterSpec
&);
393 bool Pre(const parser::ImplicitSpec
&);
394 void Post(const parser::ImplicitSpec
&);
396 const DeclTypeSpec
*GetType(
397 SourceName name
, bool respectImplicitNoneType
= true) {
398 return implicitRules_
->GetType(name
, respectImplicitNoneType
);
400 bool isImplicitNoneType() const {
401 return implicitRules_
->isImplicitNoneType();
403 bool isImplicitNoneType(const Scope
&scope
) const {
404 return implicitRulesMap_
->at(&scope
).isImplicitNoneType();
406 bool isImplicitNoneExternal() const {
407 return implicitRules_
->isImplicitNoneExternal();
409 void set_inheritFromParent(bool x
) {
410 implicitRules_
->set_inheritFromParent(x
);
414 void BeginScope(const Scope
&);
415 void SetScope(const Scope
&);
418 // implicit rules in effect for current scope
419 ImplicitRules
*implicitRules_
{nullptr};
420 std::optional
<SourceName
> prevImplicit_
;
421 std::optional
<SourceName
> prevImplicitNone_
;
422 std::optional
<SourceName
> prevImplicitNoneType_
;
423 std::optional
<SourceName
> prevParameterStmt_
;
425 bool HandleImplicitNone(const std::list
<ImplicitNoneNameSpec
> &nameSpecs
);
428 // Track array specifications. They can occur in AttrSpec, EntityDecl,
429 // ObjectDecl, DimensionStmt, CommonBlockObject, BasedPointer, and
431 // 1. INTEGER, DIMENSION(10) :: x
432 // 2. INTEGER :: x(10)
433 // 3. ALLOCATABLE :: x(:)
434 // 4. DIMENSION :: x(10)
436 // 6. POINTER(p,x(10))
437 class ArraySpecVisitor
: public virtual BaseVisitor
{
439 void Post(const parser::ArraySpec
&);
440 void Post(const parser::ComponentArraySpec
&);
441 void Post(const parser::CoarraySpec
&);
442 void Post(const parser::AttrSpec
&) { PostAttrSpec(); }
443 void Post(const parser::ComponentAttrSpec
&) { PostAttrSpec(); }
446 const ArraySpec
&arraySpec();
447 void set_arraySpec(const ArraySpec arraySpec
) { arraySpec_
= arraySpec
; }
448 const ArraySpec
&coarraySpec();
449 void BeginArraySpec();
451 void ClearArraySpec() { arraySpec_
.clear(); }
452 void ClearCoarraySpec() { coarraySpec_
.clear(); }
455 // arraySpec_/coarraySpec_ are populated from any ArraySpec/CoarraySpec
456 ArraySpec arraySpec_
;
457 ArraySpec coarraySpec_
;
458 // When an ArraySpec is under an AttrSpec or ComponentAttrSpec, it is moved
459 // into attrArraySpec_
460 ArraySpec attrArraySpec_
;
461 ArraySpec attrCoarraySpec_
;
466 // Manages a stack of function result information. We defer the processing
467 // of a type specification that appears in the prefix of a FUNCTION statement
468 // until the function result variable appears in the specification part
469 // or the end of the specification part. This allows for forward references
470 // in the type specification to resolve to local names.
471 class FuncResultStack
{
473 explicit FuncResultStack(ScopeHandler
&scopeHandler
)
474 : scopeHandler_
{scopeHandler
} {}
478 FuncInfo(const Scope
&s
, SourceName at
) : scope
{s
}, source
{at
} {}
481 // Parse tree of the type specification in the FUNCTION prefix
482 const parser::DeclarationTypeSpec
*parsedType
{nullptr};
483 // Name of the function RESULT in the FUNCTION suffix, if any
484 const parser::Name
*resultName
{nullptr};
486 Symbol
*resultSymbol
{nullptr};
487 bool inFunctionStmt
{false}; // true between Pre/Post of FunctionStmt
490 // Completes the definition of the top function's result.
491 void CompleteFunctionResultType();
492 // Completes the definition of a symbol if it is the top function's result.
493 void CompleteTypeIfFunctionResult(Symbol
&);
495 FuncInfo
*Top() { return stack_
.empty() ? nullptr : &stack_
.back(); }
496 FuncInfo
&Push(const Scope
&scope
, SourceName at
) {
497 return stack_
.emplace_back(scope
, at
);
502 ScopeHandler
&scopeHandler_
;
503 std::vector
<FuncInfo
> stack_
;
506 // Manage a stack of Scopes
507 class ScopeHandler
: public ImplicitRulesVisitor
{
509 using ImplicitRulesVisitor::Post
;
510 using ImplicitRulesVisitor::Pre
;
512 Scope
&currScope() { return DEREF(currScope_
); }
513 // The enclosing host procedure if current scope is in an internal procedure
514 Scope
*GetHostProcedure();
515 // The innermost enclosing program unit scope, ignoring BLOCK and other
517 Scope
&InclusiveScope();
518 // The enclosing scope, skipping derived types.
519 Scope
&NonDerivedTypeScope();
521 // Create a new scope and push it on the scope stack.
522 void PushScope(Scope::Kind kind
, Symbol
*symbol
);
523 void PushScope(Scope
&scope
);
525 void SetScope(Scope
&);
527 template <typename T
> bool Pre(const parser::Statement
<T
> &x
) {
528 messageHandler().set_currStmtSource(x
.source
);
529 currScope_
->AddSourceRange(x
.source
);
532 template <typename T
> void Post(const parser::Statement
<T
> &) {
533 messageHandler().set_currStmtSource(std::nullopt
);
536 // Special messages: already declared; referencing symbol's declaration;
537 // about a type; two names & locations
538 void SayAlreadyDeclared(const parser::Name
&, Symbol
&);
539 void SayAlreadyDeclared(const SourceName
&, Symbol
&);
540 void SayAlreadyDeclared(const SourceName
&, const SourceName
&);
542 const parser::Name
&, Symbol
&, MessageFixedText
&&, Message
&&);
543 template <typename
... A
>
544 Message
&SayWithDecl(
545 const parser::Name
&, Symbol
&, MessageFixedText
&&, A
&&...args
);
546 void SayLocalMustBeVariable(const parser::Name
&, Symbol
&);
547 Message
&SayDerivedType(
548 const SourceName
&, MessageFixedText
&&, const Scope
&);
549 Message
&Say2(const SourceName
&, MessageFixedText
&&, const SourceName
&,
550 MessageFixedText
&&);
552 const SourceName
&, MessageFixedText
&&, Symbol
&, MessageFixedText
&&);
554 const parser::Name
&, MessageFixedText
&&, Symbol
&, MessageFixedText
&&);
556 // Search for symbol by name in current, parent derived type, and
558 Symbol
*FindSymbol(const parser::Name
&);
559 Symbol
*FindSymbol(const Scope
&, const parser::Name
&);
560 // Search for name only in scope, not in enclosing scopes.
561 Symbol
*FindInScope(const Scope
&, const parser::Name
&);
562 Symbol
*FindInScope(const Scope
&, const SourceName
&);
563 template <typename T
> Symbol
*FindInScope(const T
&name
) {
564 return FindInScope(currScope(), name
);
566 // Search for name in a derived type scope and its parents.
567 Symbol
*FindInTypeOrParents(const Scope
&, const parser::Name
&);
568 Symbol
*FindInTypeOrParents(const parser::Name
&);
569 Symbol
*FindInScopeOrBlockConstructs(const Scope
&, SourceName
);
570 Symbol
*FindSeparateModuleProcedureInterface(const parser::Name
&);
571 void EraseSymbol(const parser::Name
&);
572 void EraseSymbol(const Symbol
&symbol
) { currScope().erase(symbol
.name()); }
573 // Make a new symbol with the name and attrs of an existing one
574 Symbol
&CopySymbol(const SourceName
&, const Symbol
&);
576 // Make symbols in the current or named scope
577 Symbol
&MakeSymbol(Scope
&, const SourceName
&, Attrs
);
578 Symbol
&MakeSymbol(const SourceName
&, Attrs
= Attrs
{});
579 Symbol
&MakeSymbol(const parser::Name
&, Attrs
= Attrs
{});
580 Symbol
&MakeHostAssocSymbol(const parser::Name
&, const Symbol
&);
582 template <typename D
>
583 common::IfNoLvalue
<Symbol
&, D
> MakeSymbol(
584 const parser::Name
&name
, D
&&details
) {
585 return MakeSymbol(name
, Attrs
{}, std::move(details
));
588 template <typename D
>
589 common::IfNoLvalue
<Symbol
&, D
> MakeSymbol(
590 const parser::Name
&name
, const Attrs
&attrs
, D
&&details
) {
591 return Resolve(name
, MakeSymbol(name
.source
, attrs
, std::move(details
)));
594 template <typename D
>
595 common::IfNoLvalue
<Symbol
&, D
> MakeSymbol(
596 const SourceName
&name
, const Attrs
&attrs
, D
&&details
) {
597 // Note: don't use FindSymbol here. If this is a derived type scope,
598 // we want to detect whether the name is already declared as a component.
599 auto *symbol
{FindInScope(name
)};
601 symbol
= &MakeSymbol(name
, attrs
);
602 symbol
->set_details(std::move(details
));
605 if constexpr (std::is_same_v
<DerivedTypeDetails
, D
>) {
606 if (auto *d
{symbol
->detailsIf
<GenericDetails
>()}) {
607 if (!d
->specific()) {
608 // derived type with same name as a generic
609 auto *derivedType
{d
->derivedType()};
612 &currScope().MakeSymbol(name
, attrs
, std::move(details
));
613 d
->set_derivedType(*derivedType
);
614 } else if (derivedType
->CanReplaceDetails(details
)) {
615 // was forward-referenced
616 CheckDuplicatedAttrs(name
, *symbol
, attrs
);
617 SetExplicitAttrs(*derivedType
, attrs
);
618 derivedType
->set_details(std::move(details
));
620 SayAlreadyDeclared(name
, *derivedType
);
625 } else if constexpr (std::is_same_v
<ProcEntityDetails
, D
>) {
626 if (auto *d
{symbol
->detailsIf
<GenericDetails
>()}) {
627 if (!d
->derivedType()) {
628 // procedure pointer with same name as a generic
629 auto *specific
{d
->specific()};
631 specific
= &currScope().MakeSymbol(name
, attrs
, std::move(details
));
632 d
->set_specific(*specific
);
634 SayAlreadyDeclared(name
, *specific
);
640 if (symbol
->CanReplaceDetails(details
)) {
641 // update the existing symbol
642 CheckDuplicatedAttrs(name
, *symbol
, attrs
);
643 SetExplicitAttrs(*symbol
, attrs
);
644 if constexpr (std::is_same_v
<SubprogramDetails
, D
>) {
645 // Dummy argument defined by explicit interface?
646 details
.set_isDummy(IsDummy(*symbol
));
648 symbol
->set_details(std::move(details
));
650 } else if constexpr (std::is_same_v
<UnknownDetails
, D
>) {
651 CheckDuplicatedAttrs(name
, *symbol
, attrs
);
652 SetExplicitAttrs(*symbol
, attrs
);
655 if (!CheckPossibleBadForwardRef(*symbol
)) {
656 if (name
.empty() && symbol
->name().empty()) {
657 // report the error elsewhere
660 Symbol
&errSym
{*symbol
};
661 if (auto *d
{symbol
->detailsIf
<GenericDetails
>()}) {
663 errSym
= *d
->specific();
664 } else if (d
->derivedType()) {
665 errSym
= *d
->derivedType();
668 SayAlreadyDeclared(name
, errSym
);
670 // replace the old symbol with a new one with correct details
671 EraseSymbol(*symbol
);
672 auto &result
{MakeSymbol(name
, attrs
, std::move(details
))};
673 context().SetError(result
);
678 void MakeExternal(Symbol
&);
680 // C815 duplicated attribute checking; returns false on error
681 bool CheckDuplicatedAttr(SourceName
, Symbol
&, Attr
);
682 bool CheckDuplicatedAttrs(SourceName
, Symbol
&, Attrs
);
684 void SetExplicitAttr(Symbol
&symbol
, Attr attr
) const {
685 symbol
.attrs().set(attr
);
686 symbol
.implicitAttrs().reset(attr
);
688 void SetExplicitAttrs(Symbol
&symbol
, Attrs attrs
) const {
689 symbol
.attrs() |= attrs
;
690 symbol
.implicitAttrs() &= ~attrs
;
692 void SetImplicitAttr(Symbol
&symbol
, Attr attr
) const {
693 symbol
.attrs().set(attr
);
694 symbol
.implicitAttrs().set(attr
);
696 void SetCUDADataAttr(
697 SourceName
, Symbol
&, std::optional
<common::CUDADataAttr
>);
700 FuncResultStack
&funcResultStack() { return funcResultStack_
; }
702 // Apply the implicit type rules to this symbol.
703 void ApplyImplicitRules(Symbol
&, bool allowForwardReference
= false);
704 bool ImplicitlyTypeForwardRef(Symbol
&);
705 void AcquireIntrinsicProcedureFlags(Symbol
&);
706 const DeclTypeSpec
*GetImplicitType(
707 Symbol
&, bool respectImplicitNoneType
= true);
708 void CheckEntryDummyUse(SourceName
, Symbol
*);
709 bool ConvertToObjectEntity(Symbol
&);
710 bool ConvertToProcEntity(Symbol
&, std::optional
<SourceName
> = std::nullopt
);
712 const DeclTypeSpec
&MakeNumericType(
713 TypeCategory
, const std::optional
<parser::KindSelector
> &);
714 const DeclTypeSpec
&MakeNumericType(TypeCategory
, int);
715 const DeclTypeSpec
&MakeLogicalType(
716 const std::optional
<parser::KindSelector
> &);
717 const DeclTypeSpec
&MakeLogicalType(int);
718 void NotePossibleBadForwardRef(const parser::Name
&);
719 std::optional
<SourceName
> HadForwardRef(const Symbol
&) const;
720 bool CheckPossibleBadForwardRef(const Symbol
&);
722 bool inSpecificationPart_
{false};
723 bool deferImplicitTyping_
{false};
724 bool skipImplicitTyping_
{false};
725 bool inEquivalenceStmt_
{false};
727 // Some information is collected from a specification part for deferred
728 // processing in DeclarationPartVisitor functions (e.g., CheckSaveStmts())
729 // that are called by ResolveNamesVisitor::FinishSpecificationPart(). Since
730 // specification parts can nest (e.g., INTERFACE bodies), the collected
731 // information that is not contained in the scope needs to be packaged
733 struct SpecificationPartState
{
734 std::set
<SourceName
> forwardRefs
;
735 // Collect equivalence sets and process at end of specification part
736 std::vector
<const std::list
<parser::EquivalenceObject
> *> equivalenceSets
;
737 // Names of all common block objects in the scope
738 std::set
<SourceName
> commonBlockObjects
;
739 // Names of all names that show in a declare target declaration
740 std::set
<SourceName
> declareTargetNames
;
741 // Info about SAVE statements and attributes in current scope
743 std::optional
<SourceName
> saveAll
; // "SAVE" without entity list
744 std::set
<SourceName
> entities
; // names of entities with save attr
745 std::set
<SourceName
> commons
; // names of common blocks with save attr
749 // Some declaration processing can and should be deferred to
750 // ResolveExecutionParts() to avoid prematurely creating implicitly-typed
751 // local symbols that should be host associations.
752 struct DeferredDeclarationState
{
753 // The content of each namelist group
754 std::list
<const parser::NamelistStmt::Group
*> namelistGroups
;
756 DeferredDeclarationState
*GetDeferredDeclarationState(bool add
= false) {
757 if (!add
&& deferred_
.find(&currScope()) == deferred_
.end()) {
760 return &deferred_
.emplace(&currScope(), DeferredDeclarationState
{})
765 void SkipImplicitTyping(bool skip
) {
766 deferImplicitTyping_
= skipImplicitTyping_
= skip
;
770 Scope
*currScope_
{nullptr};
771 FuncResultStack funcResultStack_
{*this};
772 std::map
<Scope
*, DeferredDeclarationState
> deferred_
;
775 class ModuleVisitor
: public virtual ScopeHandler
{
777 bool Pre(const parser::AccessStmt
&);
778 bool Pre(const parser::Only
&);
779 bool Pre(const parser::Rename::Names
&);
780 bool Pre(const parser::Rename::Operators
&);
781 bool Pre(const parser::UseStmt
&);
782 void Post(const parser::UseStmt
&);
784 void BeginModule(const parser::Name
&, bool isSubmodule
);
785 bool BeginSubmodule(const parser::Name
&, const parser::ParentIdentifier
&);
786 void ApplyDefaultAccess();
787 Symbol
&AddGenericUse(GenericDetails
&, const SourceName
&, const Symbol
&);
788 void AddAndCheckModuleUse(SourceName
, bool isIntrinsic
);
789 void CollectUseRenames(const parser::UseStmt
&);
790 void ClearUseRenames() { useRenames_
.clear(); }
791 void ClearUseOnly() { useOnly_
.clear(); }
792 void ClearModuleUses() {
793 intrinsicUses_
.clear();
794 nonIntrinsicUses_
.clear();
798 // The location of the last AccessStmt without access-ids, if any.
799 std::optional
<SourceName
> prevAccessStmt_
;
800 // The scope of the module during a UseStmt
801 Scope
*useModuleScope_
{nullptr};
802 // Names that have appeared in a rename clause of USE statements
803 std::set
<std::pair
<SourceName
, SourceName
>> useRenames_
;
804 // Names that have appeared in an ONLY clause of a USE statement
805 std::set
<std::pair
<SourceName
, Scope
*>> useOnly_
;
806 // Intrinsic and non-intrinsic (explicit or not) module names that
807 // have appeared in USE statements; used for C1406 warnings.
808 std::set
<SourceName
> intrinsicUses_
;
809 std::set
<SourceName
> nonIntrinsicUses_
;
811 Symbol
&SetAccess(const SourceName
&, Attr attr
, Symbol
* = nullptr);
812 // A rename in a USE statement: local => use
813 struct SymbolRename
{
814 Symbol
*local
{nullptr};
815 Symbol
*use
{nullptr};
817 // Record a use from useModuleScope_ of use Name/Symbol as local Name/Symbol
818 SymbolRename
AddUse(const SourceName
&localName
, const SourceName
&useName
);
819 SymbolRename
AddUse(const SourceName
&, const SourceName
&, Symbol
*);
821 SourceName
, SourceName
, Symbol
&localSymbol
, const Symbol
&useSymbol
);
822 void AddUse(const GenericSpecInfo
&);
823 // Record a name appearing as the target of a USE rename clause
824 void AddUseRename(SourceName name
, SourceName moduleName
) {
825 useRenames_
.emplace(std::make_pair(name
, moduleName
));
827 bool IsUseRenamed(const SourceName
&name
) const {
828 return useModuleScope_
&& useModuleScope_
->symbol() &&
829 useRenames_
.find({name
, useModuleScope_
->symbol()->name()}) !=
832 // Record a name appearing in a USE ONLY clause
833 void AddUseOnly(const SourceName
&name
) {
834 useOnly_
.emplace(std::make_pair(name
, useModuleScope_
));
836 bool IsUseOnly(const SourceName
&name
) const {
837 return useOnly_
.find({name
, useModuleScope_
}) != useOnly_
.end();
839 Scope
*FindModule(const parser::Name
&, std::optional
<bool> isIntrinsic
,
840 Scope
*ancestor
= nullptr);
843 class GenericHandler
: public virtual ScopeHandler
{
845 using ProcedureKind
= parser::ProcedureStmt::Kind
;
846 void ResolveSpecificsInGeneric(Symbol
&, bool isEndOfSpecificationPart
);
847 void DeclaredPossibleSpecificProc(Symbol
&);
849 // Mappings of generics to their as-yet specific proc names and kinds
850 using SpecificProcMapType
=
851 std::multimap
<Symbol
*, std::pair
<const parser::Name
*, ProcedureKind
>>;
852 SpecificProcMapType specificsForGenericProcs_
;
853 // inversion of SpecificProcMapType: maps pending proc names to generics
854 using GenericProcMapType
= std::multimap
<SourceName
, Symbol
*>;
855 GenericProcMapType genericsForSpecificProcs_
;
858 class InterfaceVisitor
: public virtual ScopeHandler
,
859 public virtual GenericHandler
{
861 bool Pre(const parser::InterfaceStmt
&);
862 void Post(const parser::InterfaceStmt
&);
863 void Post(const parser::EndInterfaceStmt
&);
864 bool Pre(const parser::GenericSpec
&);
865 bool Pre(const parser::ProcedureStmt
&);
866 bool Pre(const parser::GenericStmt
&);
867 void Post(const parser::GenericStmt
&);
869 bool inInterfaceBlock() const;
870 bool isGeneric() const;
871 bool isAbstract() const;
874 Symbol
&GetGenericSymbol() { return DEREF(genericInfo_
.top().symbol
); }
875 // Add to generic the symbol for the subprogram with the same name
876 void CheckGenericProcedures(Symbol
&);
879 // A new GenericInfo is pushed for each interface block and generic stmt
881 GenericInfo(bool isInterface
, bool isAbstract
= false)
882 : isInterface
{isInterface
}, isAbstract
{isAbstract
} {}
883 bool isInterface
; // in interface block
884 bool isAbstract
; // in abstract interface block
885 Symbol
*symbol
{nullptr}; // the generic symbol being defined
887 std::stack
<GenericInfo
> genericInfo_
;
888 const GenericInfo
&GetGenericInfo() const { return genericInfo_
.top(); }
889 void SetGenericSymbol(Symbol
&symbol
) { genericInfo_
.top().symbol
= &symbol
; }
890 void AddSpecificProcs(const std::list
<parser::Name
> &, ProcedureKind
);
891 void ResolveNewSpecifics();
894 class SubprogramVisitor
: public virtual ScopeHandler
, public InterfaceVisitor
{
896 bool HandleStmtFunction(const parser::StmtFunctionStmt
&);
897 bool Pre(const parser::SubroutineStmt
&);
898 bool Pre(const parser::FunctionStmt
&);
899 void Post(const parser::FunctionStmt
&);
900 bool Pre(const parser::EntryStmt
&);
901 void Post(const parser::EntryStmt
&);
902 bool Pre(const parser::InterfaceBody::Subroutine
&);
903 void Post(const parser::InterfaceBody::Subroutine
&);
904 bool Pre(const parser::InterfaceBody::Function
&);
905 void Post(const parser::InterfaceBody::Function
&);
906 bool Pre(const parser::Suffix
&);
907 bool Pre(const parser::PrefixSpec
&);
908 bool Pre(const parser::PrefixSpec::Attributes
&);
909 void Post(const parser::PrefixSpec::Launch_Bounds
&);
910 void Post(const parser::PrefixSpec::Cluster_Dims
&);
912 bool BeginSubprogram(const parser::Name
&, Symbol::Flag
,
913 bool hasModulePrefix
= false,
914 const parser::LanguageBindingSpec
* = nullptr,
915 const ProgramTree::EntryStmtList
* = nullptr);
916 bool BeginMpSubprogram(const parser::Name
&);
917 void PushBlockDataScope(const parser::Name
&);
918 void EndSubprogram(std::optional
<parser::CharBlock
> stmtSource
= std::nullopt
,
919 const std::optional
<parser::LanguageBindingSpec
> * = nullptr,
920 const ProgramTree::EntryStmtList
* = nullptr);
923 // Set when we see a stmt function that is really an array element assignment
924 bool misparsedStmtFuncFound_
{false};
927 // Edits an existing symbol created for earlier calls to a subprogram or ENTRY
928 // so that it can be replaced by a later definition.
929 bool HandlePreviousCalls(const parser::Name
&, Symbol
&, Symbol::Flag
);
930 void CheckExtantProc(const parser::Name
&, Symbol::Flag
);
931 // Create a subprogram symbol in the current scope and push a new scope.
932 Symbol
&PushSubprogramScope(const parser::Name
&, Symbol::Flag
,
933 const parser::LanguageBindingSpec
* = nullptr,
934 bool hasModulePrefix
= false);
935 Symbol
*GetSpecificFromGeneric(const parser::Name
&);
936 Symbol
&PostSubprogramStmt();
937 void CreateDummyArgument(SubprogramDetails
&, const parser::Name
&);
938 void CreateEntry(const parser::EntryStmt
&stmt
, Symbol
&subprogram
);
939 void PostEntryStmt(const parser::EntryStmt
&stmt
);
940 void HandleLanguageBinding(Symbol
*,
941 std::optional
<parser::CharBlock
> stmtSource
,
942 const std::optional
<parser::LanguageBindingSpec
> *);
945 class DeclarationVisitor
: public ArraySpecVisitor
,
946 public virtual GenericHandler
{
948 using ArraySpecVisitor::Post
;
949 using ScopeHandler::Post
;
950 using ScopeHandler::Pre
;
952 bool Pre(const parser::Initialization
&);
953 void Post(const parser::EntityDecl
&);
954 void Post(const parser::ObjectDecl
&);
955 void Post(const parser::PointerDecl
&);
956 bool Pre(const parser::BindStmt
&) { return BeginAttrs(); }
957 void Post(const parser::BindStmt
&) { EndAttrs(); }
958 bool Pre(const parser::BindEntity
&);
959 bool Pre(const parser::OldParameterStmt
&);
960 bool Pre(const parser::NamedConstantDef
&);
961 bool Pre(const parser::NamedConstant
&);
962 void Post(const parser::EnumDef
&);
963 bool Pre(const parser::Enumerator
&);
964 bool Pre(const parser::AccessSpec
&);
965 bool Pre(const parser::AsynchronousStmt
&);
966 bool Pre(const parser::ContiguousStmt
&);
967 bool Pre(const parser::ExternalStmt
&);
968 bool Pre(const parser::IntentStmt
&);
969 bool Pre(const parser::IntrinsicStmt
&);
970 bool Pre(const parser::OptionalStmt
&);
971 bool Pre(const parser::ProtectedStmt
&);
972 bool Pre(const parser::ValueStmt
&);
973 bool Pre(const parser::VolatileStmt
&);
974 bool Pre(const parser::AllocatableStmt
&) {
975 objectDeclAttr_
= Attr::ALLOCATABLE
;
978 void Post(const parser::AllocatableStmt
&) { objectDeclAttr_
= std::nullopt
; }
979 bool Pre(const parser::TargetStmt
&) {
980 objectDeclAttr_
= Attr::TARGET
;
983 bool Pre(const parser::CUDAAttributesStmt
&);
984 void Post(const parser::TargetStmt
&) { objectDeclAttr_
= std::nullopt
; }
985 void Post(const parser::DimensionStmt::Declaration
&);
986 void Post(const parser::CodimensionDecl
&);
987 bool Pre(const parser::TypeDeclarationStmt
&);
988 void Post(const parser::TypeDeclarationStmt
&);
989 void Post(const parser::IntegerTypeSpec
&);
990 void Post(const parser::UnsignedTypeSpec
&);
991 void Post(const parser::IntrinsicTypeSpec::Real
&);
992 void Post(const parser::IntrinsicTypeSpec::Complex
&);
993 void Post(const parser::IntrinsicTypeSpec::Logical
&);
994 void Post(const parser::IntrinsicTypeSpec::Character
&);
995 void Post(const parser::CharSelector::LengthAndKind
&);
996 void Post(const parser::CharLength
&);
997 void Post(const parser::LengthSelector
&);
998 bool Pre(const parser::KindParam
&);
999 bool Pre(const parser::VectorTypeSpec
&);
1000 void Post(const parser::VectorTypeSpec
&);
1001 bool Pre(const parser::DeclarationTypeSpec::Type
&);
1002 void Post(const parser::DeclarationTypeSpec::Type
&);
1003 bool Pre(const parser::DeclarationTypeSpec::Class
&);
1004 void Post(const parser::DeclarationTypeSpec::Class
&);
1005 void Post(const parser::DeclarationTypeSpec::Record
&);
1006 void Post(const parser::DerivedTypeSpec
&);
1007 bool Pre(const parser::DerivedTypeDef
&);
1008 bool Pre(const parser::DerivedTypeStmt
&);
1009 void Post(const parser::DerivedTypeStmt
&);
1010 bool Pre(const parser::TypeParamDefStmt
&) { return BeginDecl(); }
1011 void Post(const parser::TypeParamDefStmt
&);
1012 bool Pre(const parser::TypeAttrSpec::Extends
&);
1013 bool Pre(const parser::PrivateStmt
&);
1014 bool Pre(const parser::SequenceStmt
&);
1015 bool Pre(const parser::ComponentDefStmt
&) { return BeginDecl(); }
1016 void Post(const parser::ComponentDefStmt
&) { EndDecl(); }
1017 void Post(const parser::ComponentDecl
&);
1018 void Post(const parser::FillDecl
&);
1019 bool Pre(const parser::ProcedureDeclarationStmt
&);
1020 void Post(const parser::ProcedureDeclarationStmt
&);
1021 bool Pre(const parser::DataComponentDefStmt
&); // returns false
1022 bool Pre(const parser::ProcComponentDefStmt
&);
1023 void Post(const parser::ProcComponentDefStmt
&);
1024 bool Pre(const parser::ProcPointerInit
&);
1025 void Post(const parser::ProcInterface
&);
1026 void Post(const parser::ProcDecl
&);
1027 bool Pre(const parser::TypeBoundProcedurePart
&);
1028 void Post(const parser::TypeBoundProcedurePart
&);
1029 void Post(const parser::ContainsStmt
&);
1030 bool Pre(const parser::TypeBoundProcBinding
&) { return BeginAttrs(); }
1031 void Post(const parser::TypeBoundProcBinding
&) { EndAttrs(); }
1032 void Post(const parser::TypeBoundProcedureStmt::WithoutInterface
&);
1033 void Post(const parser::TypeBoundProcedureStmt::WithInterface
&);
1034 bool Pre(const parser::FinalProcedureStmt
&);
1035 bool Pre(const parser::TypeBoundGenericStmt
&);
1036 bool Pre(const parser::StructureDef
&); // returns false
1037 bool Pre(const parser::Union::UnionStmt
&);
1038 bool Pre(const parser::StructureField
&);
1039 void Post(const parser::StructureField
&);
1040 bool Pre(const parser::AllocateStmt
&);
1041 void Post(const parser::AllocateStmt
&);
1042 bool Pre(const parser::StructureConstructor
&);
1043 bool Pre(const parser::NamelistStmt::Group
&);
1044 bool Pre(const parser::IoControlSpec
&);
1045 bool Pre(const parser::CommonStmt::Block
&);
1046 bool Pre(const parser::CommonBlockObject
&);
1047 void Post(const parser::CommonBlockObject
&);
1048 bool Pre(const parser::EquivalenceStmt
&);
1049 bool Pre(const parser::SaveStmt
&);
1050 bool Pre(const parser::BasedPointer
&);
1051 void Post(const parser::BasedPointer
&);
1053 void PointerInitialization(
1054 const parser::Name
&, const parser::InitialDataTarget
&);
1055 void PointerInitialization(
1056 const parser::Name
&, const parser::ProcPointerInit
&);
1057 void NonPointerInitialization(
1058 const parser::Name
&, const parser::ConstantExpr
&);
1059 void CheckExplicitInterface(const parser::Name
&);
1060 void CheckBindings(const parser::TypeBoundProcedureStmt::WithoutInterface
&);
1062 const parser::Name
*ResolveDesignator(const parser::Designator
&);
1063 int GetVectorElementKind(
1064 TypeCategory category
, const std::optional
<parser::KindSelector
> &kind
);
1069 Symbol
&DeclareObjectEntity(const parser::Name
&, Attrs
= Attrs
{});
1070 // Make sure that there's an entity in an enclosing scope called Name
1071 Symbol
&FindOrDeclareEnclosingEntity(const parser::Name
&);
1072 // Declare a LOCAL/LOCAL_INIT/REDUCE entity while setting a locality flag. If
1073 // there isn't a type specified it comes from the entity in the containing
1074 // scope, or implicit rules.
1075 void DeclareLocalEntity(const parser::Name
&, Symbol::Flag
);
1076 // Declare a statement entity (i.e., an implied DO loop index for
1077 // a DATA statement or an array constructor). If there isn't an explict
1078 // type specified, implicit rules apply. Return pointer to the new symbol,
1079 // or nullptr on error.
1080 Symbol
*DeclareStatementEntity(const parser::DoVariable
&,
1081 const std::optional
<parser::IntegerTypeSpec
> &);
1082 Symbol
&MakeCommonBlockSymbol(const parser::Name
&);
1083 Symbol
&MakeCommonBlockSymbol(const std::optional
<parser::Name
> &);
1084 bool CheckUseError(const parser::Name
&);
1085 void CheckAccessibility(const SourceName
&, bool, Symbol
&);
1086 void CheckCommonBlocks();
1087 void CheckSaveStmts();
1088 void CheckEquivalenceSets();
1089 bool CheckNotInBlock(const char *);
1090 bool NameIsKnownOrIntrinsic(const parser::Name
&);
1091 void FinishNamelists();
1093 // Each of these returns a pointer to a resolved Name (i.e. with symbol)
1094 // or nullptr in case of error.
1095 const parser::Name
*ResolveStructureComponent(
1096 const parser::StructureComponent
&);
1097 const parser::Name
*ResolveDataRef(const parser::DataRef
&);
1098 const parser::Name
*ResolveName(const parser::Name
&);
1099 bool PassesSharedLocalityChecks(const parser::Name
&name
, Symbol
&symbol
);
1100 Symbol
*NoteInterfaceName(const parser::Name
&);
1101 bool IsUplevelReference(const Symbol
&);
1103 std::optional
<SourceName
> BeginCheckOnIndexUseInOwnBounds(
1104 const parser::DoVariable
&name
) {
1105 std::optional
<SourceName
> result
{checkIndexUseInOwnBounds_
};
1106 checkIndexUseInOwnBounds_
= name
.thing
.thing
.source
;
1109 void EndCheckOnIndexUseInOwnBounds(const std::optional
<SourceName
> &restore
) {
1110 checkIndexUseInOwnBounds_
= restore
;
1112 void NoteScalarSpecificationArgument(const Symbol
&symbol
) {
1113 mustBeScalar_
.emplace(symbol
);
1115 // Declare an object or procedure entity.
1116 // T is one of: EntityDetails, ObjectEntityDetails, ProcEntityDetails
1117 template <typename T
>
1118 Symbol
&DeclareEntity(const parser::Name
&name
, Attrs attrs
) {
1119 Symbol
&symbol
{MakeSymbol(name
, attrs
)};
1120 if (context().HasError(symbol
) || symbol
.has
<T
>()) {
1121 return symbol
; // OK or error already reported
1122 } else if (symbol
.has
<UnknownDetails
>()) {
1123 symbol
.set_details(T
{});
1125 } else if (auto *details
{symbol
.detailsIf
<EntityDetails
>()}) {
1126 symbol
.set_details(T
{std::move(*details
)});
1128 } else if (std::is_same_v
<EntityDetails
, T
> &&
1129 (symbol
.has
<ObjectEntityDetails
>() ||
1130 symbol
.has
<ProcEntityDetails
>())) {
1131 return symbol
; // OK
1132 } else if (auto *details
{symbol
.detailsIf
<UseDetails
>()}) {
1134 "'%s' is use-associated from module '%s' and cannot be re-declared"_err_en_US
,
1135 name
.source
, GetUsedModule(*details
).name());
1136 } else if (auto *details
{symbol
.detailsIf
<SubprogramNameDetails
>()}) {
1137 if (details
->kind() == SubprogramKind::Module
) {
1139 "Declaration of '%s' conflicts with its use as module procedure"_err_en_US
,
1140 symbol
, "Module procedure definition"_en_US
);
1141 } else if (details
->kind() == SubprogramKind::Internal
) {
1143 "Declaration of '%s' conflicts with its use as internal procedure"_err_en_US
,
1144 symbol
, "Internal procedure definition"_en_US
);
1146 DIE("unexpected kind");
1148 } else if (std::is_same_v
<ObjectEntityDetails
, T
> &&
1149 symbol
.has
<ProcEntityDetails
>()) {
1151 name
, symbol
, "'%s' is already declared as a procedure"_err_en_US
);
1152 } else if (std::is_same_v
<ProcEntityDetails
, T
> &&
1153 symbol
.has
<ObjectEntityDetails
>()) {
1154 if (FindCommonBlockContaining(symbol
)) {
1155 SayWithDecl(name
, symbol
,
1156 "'%s' may not be a procedure as it is in a COMMON block"_err_en_US
);
1159 name
, symbol
, "'%s' is already declared as an object"_err_en_US
);
1161 } else if (!CheckPossibleBadForwardRef(symbol
)) {
1162 SayAlreadyDeclared(name
, symbol
);
1164 context().SetError(symbol
);
1169 // The attribute corresponding to the statement containing an ObjectDecl
1170 std::optional
<Attr
> objectDeclAttr_
;
1171 // Info about current character type while walking DeclTypeSpec.
1172 // Also captures any "*length" specifier on an individual declaration.
1174 std::optional
<ParamValue
> length
;
1175 std::optional
<KindExpr
> kind
;
1177 // Info about current derived type or STRUCTURE while walking
1178 // DerivedTypeDef / StructureDef
1180 const parser::Name
*extends
{nullptr}; // EXTENDS(name)
1181 bool privateComps
{false}; // components are private by default
1182 bool privateBindings
{false}; // bindings are private by default
1183 bool sawContains
{false}; // currently processing bindings
1184 bool sequence
{false}; // is a sequence type
1185 const Symbol
*type
{nullptr}; // derived type being defined
1186 bool isStructure
{false}; // is a DEC STRUCTURE
1188 // In a ProcedureDeclarationStmt or ProcComponentDefStmt, this is
1189 // the interface name, if any.
1190 const parser::Name
*interfaceName_
{nullptr};
1191 // Map type-bound generic to binding names of its specific bindings
1192 std::multimap
<Symbol
*, const parser::Name
*> genericBindings_
;
1193 // Info about current ENUM
1194 struct EnumeratorState
{
1195 // Enum value must hold inside a C_INT (7.6.2).
1196 std::optional
<int> value
{0};
1197 } enumerationState_
;
1198 // Set for OldParameterStmt processing
1199 bool inOldStyleParameterStmt_
{false};
1200 // Set when walking DATA & array constructor implied DO loop bounds
1201 // to warn about use of the implied DO intex therein.
1202 std::optional
<SourceName
> checkIndexUseInOwnBounds_
;
1203 bool isVectorType_
{false};
1204 UnorderedSymbolSet mustBeScalar_
;
1206 bool HandleAttributeStmt(Attr
, const std::list
<parser::Name
> &);
1207 Symbol
&HandleAttributeStmt(Attr
, const parser::Name
&);
1208 Symbol
&DeclareUnknownEntity(const parser::Name
&, Attrs
);
1209 Symbol
&DeclareProcEntity(
1210 const parser::Name
&, Attrs
, const Symbol
*interface
);
1211 void SetType(const parser::Name
&, const DeclTypeSpec
&);
1212 std::optional
<DerivedTypeSpec
> ResolveDerivedType(const parser::Name
&);
1213 std::optional
<DerivedTypeSpec
> ResolveExtendsType(
1214 const parser::Name
&, const parser::Name
*);
1215 Symbol
*MakeTypeSymbol(const SourceName
&, Details
&&);
1216 Symbol
*MakeTypeSymbol(const parser::Name
&, Details
&&);
1217 bool OkToAddComponent(const parser::Name
&, const Symbol
*extends
= nullptr);
1218 ParamValue
GetParamValue(
1219 const parser::TypeParamValue
&, common::TypeParamAttr attr
);
1220 void CheckCommonBlockDerivedType(
1221 const SourceName
&, const Symbol
&, UnorderedSymbolSet
&);
1222 Attrs
HandleSaveName(const SourceName
&, Attrs
);
1223 void AddSaveName(std::set
<SourceName
> &, const SourceName
&);
1224 bool HandleUnrestrictedSpecificIntrinsicFunction(const parser::Name
&);
1225 const parser::Name
*FindComponent(const parser::Name
*, const parser::Name
&);
1226 void Initialization(const parser::Name
&, const parser::Initialization
&,
1227 bool inComponentDecl
);
1228 bool FindAndMarkDeclareTargetSymbol(const parser::Name
&);
1229 bool PassesLocalityChecks(
1230 const parser::Name
&name
, Symbol
&symbol
, Symbol::Flag flag
);
1231 bool CheckForHostAssociatedImplicit(const parser::Name
&);
1232 bool HasCycle(const Symbol
&, const Symbol
*interface
);
1233 bool MustBeScalar(const Symbol
&symbol
) const {
1234 return mustBeScalar_
.find(symbol
) != mustBeScalar_
.end();
1236 void DeclareIntrinsic(const parser::Name
&);
1239 // Resolve construct entities and statement entities.
1240 // Check that construct names don't conflict with other names.
1241 class ConstructVisitor
: public virtual DeclarationVisitor
{
1243 bool Pre(const parser::ConcurrentHeader
&);
1244 bool Pre(const parser::LocalitySpec::Local
&);
1245 bool Pre(const parser::LocalitySpec::LocalInit
&);
1246 bool Pre(const parser::LocalitySpec::Reduce
&);
1247 bool Pre(const parser::LocalitySpec::Shared
&);
1248 bool Pre(const parser::AcSpec
&);
1249 bool Pre(const parser::AcImpliedDo
&);
1250 bool Pre(const parser::DataImpliedDo
&);
1251 bool Pre(const parser::DataIDoObject
&);
1252 bool Pre(const parser::DataStmtObject
&);
1253 bool Pre(const parser::DataStmtValue
&);
1254 bool Pre(const parser::DoConstruct
&);
1255 void Post(const parser::DoConstruct
&);
1256 bool Pre(const parser::ForallConstruct
&);
1257 void Post(const parser::ForallConstruct
&);
1258 bool Pre(const parser::ForallStmt
&);
1259 void Post(const parser::ForallStmt
&);
1260 bool Pre(const parser::BlockConstruct
&);
1261 void Post(const parser::Selector
&);
1262 void Post(const parser::AssociateStmt
&);
1263 void Post(const parser::EndAssociateStmt
&);
1264 bool Pre(const parser::Association
&);
1265 void Post(const parser::SelectTypeStmt
&);
1266 void Post(const parser::SelectRankStmt
&);
1267 bool Pre(const parser::SelectTypeConstruct
&);
1268 void Post(const parser::SelectTypeConstruct
&);
1269 bool Pre(const parser::SelectTypeConstruct::TypeCase
&);
1270 void Post(const parser::SelectTypeConstruct::TypeCase
&);
1271 // Creates Block scopes with neither symbol name nor symbol details.
1272 bool Pre(const parser::SelectRankConstruct::RankCase
&);
1273 void Post(const parser::SelectRankConstruct::RankCase
&);
1274 bool Pre(const parser::TypeGuardStmt::Guard
&);
1275 void Post(const parser::TypeGuardStmt::Guard
&);
1276 void Post(const parser::SelectRankCaseStmt::Rank
&);
1277 bool Pre(const parser::ChangeTeamStmt
&);
1278 void Post(const parser::EndChangeTeamStmt
&);
1279 void Post(const parser::CoarrayAssociation
&);
1281 // Definitions of construct names
1282 bool Pre(const parser::WhereConstructStmt
&x
) { return CheckDef(x
.t
); }
1283 bool Pre(const parser::ForallConstructStmt
&x
) { return CheckDef(x
.t
); }
1284 bool Pre(const parser::CriticalStmt
&x
) { return CheckDef(x
.t
); }
1285 bool Pre(const parser::LabelDoStmt
&) {
1286 return false; // error recovery
1288 bool Pre(const parser::NonLabelDoStmt
&x
) { return CheckDef(x
.t
); }
1289 bool Pre(const parser::IfThenStmt
&x
) { return CheckDef(x
.t
); }
1290 bool Pre(const parser::SelectCaseStmt
&x
) { return CheckDef(x
.t
); }
1291 bool Pre(const parser::SelectRankConstruct
&);
1292 void Post(const parser::SelectRankConstruct
&);
1293 bool Pre(const parser::SelectRankStmt
&x
) {
1294 return CheckDef(std::get
<0>(x
.t
));
1296 bool Pre(const parser::SelectTypeStmt
&x
) {
1297 return CheckDef(std::get
<0>(x
.t
));
1300 // References to construct names
1301 void Post(const parser::MaskedElsewhereStmt
&x
) { CheckRef(x
.t
); }
1302 void Post(const parser::ElsewhereStmt
&x
) { CheckRef(x
.v
); }
1303 void Post(const parser::EndWhereStmt
&x
) { CheckRef(x
.v
); }
1304 void Post(const parser::EndForallStmt
&x
) { CheckRef(x
.v
); }
1305 void Post(const parser::EndCriticalStmt
&x
) { CheckRef(x
.v
); }
1306 void Post(const parser::EndDoStmt
&x
) { CheckRef(x
.v
); }
1307 void Post(const parser::ElseIfStmt
&x
) { CheckRef(x
.t
); }
1308 void Post(const parser::ElseStmt
&x
) { CheckRef(x
.v
); }
1309 void Post(const parser::EndIfStmt
&x
) { CheckRef(x
.v
); }
1310 void Post(const parser::CaseStmt
&x
) { CheckRef(x
.t
); }
1311 void Post(const parser::EndSelectStmt
&x
) { CheckRef(x
.v
); }
1312 void Post(const parser::SelectRankCaseStmt
&x
) { CheckRef(x
.t
); }
1313 void Post(const parser::TypeGuardStmt
&x
) { CheckRef(x
.t
); }
1314 void Post(const parser::CycleStmt
&x
) { CheckRef(x
.v
); }
1315 void Post(const parser::ExitStmt
&x
) { CheckRef(x
.v
); }
1317 void HandleImpliedAsynchronousInScope(const parser::Block
&);
1320 // R1105 selector -> expr | variable
1321 // expr is set in either case unless there were errors
1324 Selector(const SourceName
&source
, MaybeExpr
&&expr
)
1325 : source
{source
}, expr
{std::move(expr
)} {}
1326 operator bool() const { return expr
.has_value(); }
1327 parser::CharBlock source
;
1330 // association -> [associate-name =>] selector
1331 struct Association
{
1332 const parser::Name
*name
{nullptr};
1335 std::vector
<Association
> associationStack_
;
1336 Association
*currentAssociation_
{nullptr};
1338 template <typename T
> bool CheckDef(const T
&t
) {
1339 return CheckDef(std::get
<std::optional
<parser::Name
>>(t
));
1341 template <typename T
> void CheckRef(const T
&t
) {
1342 CheckRef(std::get
<std::optional
<parser::Name
>>(t
));
1344 bool CheckDef(const std::optional
<parser::Name
> &);
1345 void CheckRef(const std::optional
<parser::Name
> &);
1346 const DeclTypeSpec
&ToDeclTypeSpec(evaluate::DynamicType
&&);
1347 const DeclTypeSpec
&ToDeclTypeSpec(
1348 evaluate::DynamicType
&&, MaybeSubscriptIntExpr
&&length
);
1349 Symbol
*MakeAssocEntity();
1350 void SetTypeFromAssociation(Symbol
&);
1351 void SetAttrsFromAssociation(Symbol
&);
1352 Selector
ResolveSelector(const parser::Selector
&);
1353 void ResolveIndexName(const parser::ConcurrentControl
&control
);
1354 void SetCurrentAssociation(std::size_t n
);
1355 Association
&GetCurrentAssociation();
1356 void PushAssociation();
1357 void PopAssociation(std::size_t count
= 1);
1360 // Create scopes for OpenACC constructs
1361 class AccVisitor
: public virtual DeclarationVisitor
{
1363 void AddAccSourceRange(const parser::CharBlock
&);
1365 static bool NeedsScope(const parser::OpenACCBlockConstruct
&);
1367 bool Pre(const parser::OpenACCBlockConstruct
&);
1368 void Post(const parser::OpenACCBlockConstruct
&);
1369 bool Pre(const parser::OpenACCCombinedConstruct
&);
1370 void Post(const parser::OpenACCCombinedConstruct
&);
1371 bool Pre(const parser::AccBeginBlockDirective
&x
) {
1372 AddAccSourceRange(x
.source
);
1375 void Post(const parser::AccBeginBlockDirective
&) {
1376 messageHandler().set_currStmtSource(std::nullopt
);
1378 bool Pre(const parser::AccEndBlockDirective
&x
) {
1379 AddAccSourceRange(x
.source
);
1382 void Post(const parser::AccEndBlockDirective
&) {
1383 messageHandler().set_currStmtSource(std::nullopt
);
1385 bool Pre(const parser::AccBeginLoopDirective
&x
) {
1386 AddAccSourceRange(x
.source
);
1389 void Post(const parser::AccBeginLoopDirective
&x
) {
1390 messageHandler().set_currStmtSource(std::nullopt
);
1394 bool AccVisitor::NeedsScope(const parser::OpenACCBlockConstruct
&x
) {
1395 const auto &beginBlockDir
{std::get
<parser::AccBeginBlockDirective
>(x
.t
)};
1396 const auto &beginDir
{std::get
<parser::AccBlockDirective
>(beginBlockDir
.t
)};
1397 switch (beginDir
.v
) {
1398 case llvm::acc::Directive::ACCD_data
:
1399 case llvm::acc::Directive::ACCD_host_data
:
1400 case llvm::acc::Directive::ACCD_kernels
:
1401 case llvm::acc::Directive::ACCD_parallel
:
1402 case llvm::acc::Directive::ACCD_serial
:
1409 void AccVisitor::AddAccSourceRange(const parser::CharBlock
&source
) {
1410 messageHandler().set_currStmtSource(source
);
1411 currScope().AddSourceRange(source
);
1414 bool AccVisitor::Pre(const parser::OpenACCBlockConstruct
&x
) {
1415 if (NeedsScope(x
)) {
1416 PushScope(Scope::Kind::OpenACCConstruct
, nullptr);
1421 void AccVisitor::Post(const parser::OpenACCBlockConstruct
&x
) {
1422 if (NeedsScope(x
)) {
1427 bool AccVisitor::Pre(const parser::OpenACCCombinedConstruct
&x
) {
1428 PushScope(Scope::Kind::OpenACCConstruct
, nullptr);
1432 void AccVisitor::Post(const parser::OpenACCCombinedConstruct
&x
) { PopScope(); }
1434 // Create scopes for OpenMP constructs
1435 class OmpVisitor
: public virtual DeclarationVisitor
{
1437 void AddOmpSourceRange(const parser::CharBlock
&);
1439 static bool NeedsScope(const parser::OpenMPBlockConstruct
&);
1440 static bool NeedsScope(const parser::OmpClause
&);
1442 bool Pre(const parser::OpenMPRequiresConstruct
&x
) {
1443 AddOmpSourceRange(x
.source
);
1446 bool Pre(const parser::OmpSimpleStandaloneDirective
&x
) {
1447 AddOmpSourceRange(x
.source
);
1450 bool Pre(const parser::OpenMPBlockConstruct
&);
1451 void Post(const parser::OpenMPBlockConstruct
&);
1452 bool Pre(const parser::OmpBeginBlockDirective
&x
) {
1453 AddOmpSourceRange(x
.source
);
1456 void Post(const parser::OmpBeginBlockDirective
&) {
1457 messageHandler().set_currStmtSource(std::nullopt
);
1459 bool Pre(const parser::OmpEndBlockDirective
&x
) {
1460 AddOmpSourceRange(x
.source
);
1463 void Post(const parser::OmpEndBlockDirective
&) {
1464 messageHandler().set_currStmtSource(std::nullopt
);
1467 bool Pre(const parser::OpenMPLoopConstruct
&) {
1468 PushScope(Scope::Kind::OtherConstruct
, nullptr);
1471 void Post(const parser::OpenMPLoopConstruct
&) { PopScope(); }
1472 bool Pre(const parser::OmpBeginLoopDirective
&x
) {
1473 AddOmpSourceRange(x
.source
);
1477 bool Pre(const parser::OpenMPDeclareMapperConstruct
&);
1479 bool Pre(const parser::OmpMapClause
&);
1481 void Post(const parser::OmpBeginLoopDirective
&) {
1482 messageHandler().set_currStmtSource(std::nullopt
);
1484 bool Pre(const parser::OmpEndLoopDirective
&x
) {
1485 AddOmpSourceRange(x
.source
);
1488 void Post(const parser::OmpEndLoopDirective
&) {
1489 messageHandler().set_currStmtSource(std::nullopt
);
1492 bool Pre(const parser::OpenMPSectionsConstruct
&) {
1493 PushScope(Scope::Kind::OtherConstruct
, nullptr);
1496 void Post(const parser::OpenMPSectionsConstruct
&) { PopScope(); }
1497 bool Pre(const parser::OmpBeginSectionsDirective
&x
) {
1498 AddOmpSourceRange(x
.source
);
1501 void Post(const parser::OmpBeginSectionsDirective
&) {
1502 messageHandler().set_currStmtSource(std::nullopt
);
1504 bool Pre(const parser::OmpEndSectionsDirective
&x
) {
1505 AddOmpSourceRange(x
.source
);
1508 void Post(const parser::OmpEndSectionsDirective
&) {
1509 messageHandler().set_currStmtSource(std::nullopt
);
1511 bool Pre(const parser::OmpCriticalDirective
&x
) {
1512 AddOmpSourceRange(x
.source
);
1515 void Post(const parser::OmpCriticalDirective
&) {
1516 messageHandler().set_currStmtSource(std::nullopt
);
1518 bool Pre(const parser::OmpEndCriticalDirective
&x
) {
1519 AddOmpSourceRange(x
.source
);
1522 void Post(const parser::OmpEndCriticalDirective
&) {
1523 messageHandler().set_currStmtSource(std::nullopt
);
1525 bool Pre(const parser::OpenMPThreadprivate
&) {
1526 SkipImplicitTyping(true);
1529 void Post(const parser::OpenMPThreadprivate
&) { SkipImplicitTyping(false); }
1530 bool Pre(const parser::OpenMPDeclareTargetConstruct
&x
) {
1531 const auto &spec
{std::get
<parser::OmpDeclareTargetSpecifier
>(x
.t
)};
1532 auto populateDeclareTargetNames
{
1533 [this](const parser::OmpObjectList
&objectList
) {
1534 for (const auto &ompObject
: objectList
.v
) {
1537 [&](const parser::Designator
&designator
) {
1538 if (const auto *name
{
1539 semantics::getDesignatorNameIfDataRef(
1541 specPartState_
.declareTargetNames
.insert(name
->source
);
1544 [&](const parser::Name
&name
) {
1545 specPartState_
.declareTargetNames
.insert(name
.source
);
1552 if (const auto *objectList
{parser::Unwrap
<parser::OmpObjectList
>(spec
.u
)}) {
1553 populateDeclareTargetNames(*objectList
);
1554 } else if (const auto *clauseList
{
1555 parser::Unwrap
<parser::OmpClauseList
>(spec
.u
)}) {
1556 for (const auto &clause
: clauseList
->v
) {
1557 if (const auto *toClause
{
1558 std::get_if
<parser::OmpClause::To
>(&clause
.u
)}) {
1559 populateDeclareTargetNames(
1560 std::get
<parser::OmpObjectList
>(toClause
->v
.t
));
1561 } else if (const auto *linkClause
{
1562 std::get_if
<parser::OmpClause::Link
>(&clause
.u
)}) {
1563 populateDeclareTargetNames(linkClause
->v
);
1564 } else if (const auto *enterClause
{
1565 std::get_if
<parser::OmpClause::Enter
>(&clause
.u
)}) {
1566 populateDeclareTargetNames(enterClause
->v
);
1571 SkipImplicitTyping(true);
1574 void Post(const parser::OpenMPDeclareTargetConstruct
&) {
1575 SkipImplicitTyping(false);
1577 bool Pre(const parser::OpenMPDeclarativeAllocate
&) {
1578 SkipImplicitTyping(true);
1581 void Post(const parser::OpenMPDeclarativeAllocate
&) {
1582 SkipImplicitTyping(false);
1584 bool Pre(const parser::OpenMPDeclarativeConstruct
&x
) {
1585 AddOmpSourceRange(x
.source
);
1588 void Post(const parser::OpenMPDeclarativeConstruct
&) {
1589 messageHandler().set_currStmtSource(std::nullopt
);
1591 bool Pre(const parser::OpenMPDepobjConstruct
&x
) {
1592 AddOmpSourceRange(x
.source
);
1595 void Post(const parser::OpenMPDepobjConstruct
&x
) {
1596 messageHandler().set_currStmtSource(std::nullopt
);
1598 bool Pre(const parser::OpenMPAtomicConstruct
&x
) {
1599 return common::visit(common::visitors
{[&](const auto &u
) -> bool {
1600 AddOmpSourceRange(u
.source
);
1605 void Post(const parser::OpenMPAtomicConstruct
&) {
1606 messageHandler().set_currStmtSource(std::nullopt
);
1608 bool Pre(const parser::OmpClause
&x
) {
1609 if (NeedsScope(x
)) {
1610 PushScope(Scope::Kind::OtherClause
, nullptr);
1614 void Post(const parser::OmpClause
&x
) {
1615 if (NeedsScope(x
)) {
1621 bool OmpVisitor::NeedsScope(const parser::OpenMPBlockConstruct
&x
) {
1622 const auto &beginBlockDir
{std::get
<parser::OmpBeginBlockDirective
>(x
.t
)};
1623 const auto &beginDir
{std::get
<parser::OmpBlockDirective
>(beginBlockDir
.t
)};
1624 switch (beginDir
.v
) {
1625 case llvm::omp::Directive::OMPD_master
:
1626 case llvm::omp::Directive::OMPD_ordered
:
1627 case llvm::omp::Directive::OMPD_taskgroup
:
1634 bool OmpVisitor::NeedsScope(const parser::OmpClause
&x
) {
1635 // Iterators contain declarations, whose scope extends until the end
1637 return llvm::omp::canHaveIterator(x
.Id());
1640 void OmpVisitor::AddOmpSourceRange(const parser::CharBlock
&source
) {
1641 messageHandler().set_currStmtSource(source
);
1642 currScope().AddSourceRange(source
);
1645 bool OmpVisitor::Pre(const parser::OpenMPBlockConstruct
&x
) {
1646 if (NeedsScope(x
)) {
1647 PushScope(Scope::Kind::OtherConstruct
, nullptr);
1652 void OmpVisitor::Post(const parser::OpenMPBlockConstruct
&x
) {
1653 if (NeedsScope(x
)) {
1658 // This "manually" walks the tree of the construct, because we need
1659 // to resolve the type before the map clauses are processed - when
1660 // just following the natural flow, the map clauses gets processed before
1661 // the type has been fully processed.
1662 bool OmpVisitor::Pre(const parser::OpenMPDeclareMapperConstruct
&x
) {
1663 AddOmpSourceRange(x
.source
);
1664 BeginDeclTypeSpec();
1665 const auto &spec
{std::get
<parser::OmpDeclareMapperSpecifier
>(x
.t
)};
1666 Symbol
*mapperSym
{nullptr};
1667 if (const auto &mapperName
{std::get
<std::optional
<parser::Name
>>(spec
.t
)}) {
1669 &MakeSymbol(*mapperName
, MiscDetails
{MiscDetails::Kind::ConstructName
});
1670 mapperName
->symbol
= mapperSym
;
1672 const parser::CharBlock defaultName
{"default", 7};
1673 mapperSym
= &MakeSymbol(
1674 defaultName
, Attrs
{}, MiscDetails
{MiscDetails::Kind::ConstructName
});
1677 PushScope(Scope::Kind::OtherConstruct
, nullptr);
1678 Walk(std::get
<parser::TypeSpec
>(spec
.t
));
1679 const auto &varName
{std::get
<parser::ObjectName
>(spec
.t
)};
1680 DeclareObjectEntity(varName
);
1682 Walk(std::get
<parser::OmpClauseList
>(x
.t
));
1689 bool OmpVisitor::Pre(const parser::OmpMapClause
&x
) {
1690 auto &mods
{OmpGetModifiers(x
)};
1691 if (auto *mapper
{OmpGetUniqueModifier
<parser::OmpMapper
>(mods
)}) {
1692 if (auto *symbol
{FindSymbol(currScope(), mapper
->v
)}) {
1693 // TODO: Do we need a specific flag or type here, to distinghuish against
1694 // other ConstructName things? Leaving this for the full implementation
1695 // of mapper lowering.
1696 auto *misc
{symbol
->detailsIf
<MiscDetails
>()};
1697 if (!misc
|| misc
->kind() != MiscDetails::Kind::ConstructName
)
1698 context().Say(mapper
->v
.source
,
1699 "Name '%s' should be a mapper name"_err_en_US
, mapper
->v
.source
);
1701 mapper
->v
.symbol
= symbol
;
1704 &MakeSymbol(mapper
->v
, MiscDetails
{MiscDetails::Kind::ConstructName
});
1705 // TODO: When completing the implementation, we probably want to error if
1706 // the symbol is not declared, but right now, testing that the TODO for
1707 // OmpMapClause happens is obscured by the TODO for declare mapper, so
1708 // leaving this out. Remove the above line once the declare mapper is
1709 // implemented. context().Say(mapper->v.source, "'%s' not
1710 // declared"_err_en_US, mapper->v.source);
1716 // Walk the parse tree and resolve names to symbols.
1717 class ResolveNamesVisitor
: public virtual ScopeHandler
,
1718 public ModuleVisitor
,
1719 public SubprogramVisitor
,
1720 public ConstructVisitor
,
1724 using AccVisitor::Post
;
1725 using AccVisitor::Pre
;
1726 using ArraySpecVisitor::Post
;
1727 using ConstructVisitor::Post
;
1728 using ConstructVisitor::Pre
;
1729 using DeclarationVisitor::Post
;
1730 using DeclarationVisitor::Pre
;
1731 using ImplicitRulesVisitor::Post
;
1732 using ImplicitRulesVisitor::Pre
;
1733 using InterfaceVisitor::Post
;
1734 using InterfaceVisitor::Pre
;
1735 using ModuleVisitor::Post
;
1736 using ModuleVisitor::Pre
;
1737 using OmpVisitor::Post
;
1738 using OmpVisitor::Pre
;
1739 using ScopeHandler::Post
;
1740 using ScopeHandler::Pre
;
1741 using SubprogramVisitor::Post
;
1742 using SubprogramVisitor::Pre
;
1744 ResolveNamesVisitor(
1745 SemanticsContext
&context
, ImplicitRulesMap
&rules
, Scope
&top
)
1746 : BaseVisitor
{context
, *this, rules
}, topScope_
{top
} {
1750 Scope
&topScope() const { return topScope_
; }
1752 // Default action for a parse tree node is to visit children.
1753 template <typename T
> bool Pre(const T
&) { return true; }
1754 template <typename T
> void Post(const T
&) {}
1756 bool Pre(const parser::SpecificationPart
&);
1757 bool Pre(const parser::Program
&);
1758 void Post(const parser::Program
&);
1759 bool Pre(const parser::ImplicitStmt
&);
1760 void Post(const parser::PointerObject
&);
1761 void Post(const parser::AllocateObject
&);
1762 bool Pre(const parser::PointerAssignmentStmt
&);
1763 void Post(const parser::Designator
&);
1764 void Post(const parser::SubstringInquiry
&);
1765 template <typename A
, typename B
>
1766 void Post(const parser::LoopBounds
<A
, B
> &x
) {
1767 ResolveName(*parser::Unwrap
<parser::Name
>(x
.name
));
1769 void Post(const parser::ProcComponentRef
&);
1770 bool Pre(const parser::FunctionReference
&);
1771 bool Pre(const parser::CallStmt
&);
1772 bool Pre(const parser::ImportStmt
&);
1773 void Post(const parser::TypeGuardStmt
&);
1774 bool Pre(const parser::StmtFunctionStmt
&);
1775 bool Pre(const parser::DefinedOpName
&);
1776 bool Pre(const parser::ProgramUnit
&);
1777 void Post(const parser::AssignStmt
&);
1778 void Post(const parser::AssignedGotoStmt
&);
1779 void Post(const parser::CompilerDirective
&);
1781 // These nodes should never be reached: they are handled in ProgramUnit
1782 bool Pre(const parser::MainProgram
&) {
1783 llvm_unreachable("This node is handled in ProgramUnit");
1785 bool Pre(const parser::FunctionSubprogram
&) {
1786 llvm_unreachable("This node is handled in ProgramUnit");
1788 bool Pre(const parser::SubroutineSubprogram
&) {
1789 llvm_unreachable("This node is handled in ProgramUnit");
1791 bool Pre(const parser::SeparateModuleSubprogram
&) {
1792 llvm_unreachable("This node is handled in ProgramUnit");
1794 bool Pre(const parser::Module
&) {
1795 llvm_unreachable("This node is handled in ProgramUnit");
1797 bool Pre(const parser::Submodule
&) {
1798 llvm_unreachable("This node is handled in ProgramUnit");
1800 bool Pre(const parser::BlockData
&) {
1801 llvm_unreachable("This node is handled in ProgramUnit");
1804 void NoteExecutablePartCall(Symbol::Flag
, SourceName
, bool hasCUDAChevrons
);
1806 friend void ResolveSpecificationParts(SemanticsContext
&, const Symbol
&);
1809 // Kind of procedure we are expecting to see in a ProcedureDesignator
1810 std::optional
<Symbol::Flag
> expectedProcFlag_
;
1811 std::optional
<SourceName
> prevImportStmt_
;
1814 void PreSpecificationConstruct(const parser::SpecificationConstruct
&);
1815 void CreateCommonBlockSymbols(const parser::CommonStmt
&);
1816 void CreateObjectSymbols(const std::list
<parser::ObjectDecl
> &, Attr
);
1817 void CreateGeneric(const parser::GenericSpec
&);
1818 void FinishSpecificationPart(const std::list
<parser::DeclarationConstruct
> &);
1819 void AnalyzeStmtFunctionStmt(const parser::StmtFunctionStmt
&);
1820 void CheckImports();
1821 void CheckImport(const SourceName
&, const SourceName
&);
1822 void HandleCall(Symbol::Flag
, const parser::Call
&);
1823 void HandleProcedureName(Symbol::Flag
, const parser::Name
&);
1824 bool CheckImplicitNoneExternal(const SourceName
&, const Symbol
&);
1825 bool SetProcFlag(const parser::Name
&, Symbol
&, Symbol::Flag
);
1826 void ResolveSpecificationParts(ProgramTree
&);
1827 void AddSubpNames(ProgramTree
&);
1828 bool BeginScopeForNode(const ProgramTree
&);
1829 void EndScopeForNode(const ProgramTree
&);
1830 void FinishSpecificationParts(const ProgramTree
&);
1831 void FinishExecutionParts(const ProgramTree
&);
1832 void FinishDerivedTypeInstantiation(Scope
&);
1833 void ResolveExecutionParts(const ProgramTree
&);
1834 void UseCUDABuiltinNames();
1835 void HandleDerivedTypesInImplicitStmts(const parser::ImplicitPart
&,
1836 const std::list
<parser::DeclarationConstruct
> &);
1839 // ImplicitRules implementation
1841 bool ImplicitRules::isImplicitNoneType() const {
1842 if (isImplicitNoneType_
) {
1844 } else if (map_
.empty() && inheritFromParent_
) {
1845 return parent_
->isImplicitNoneType();
1847 return false; // default if not specified
1851 bool ImplicitRules::isImplicitNoneExternal() const {
1852 if (isImplicitNoneExternal_
) {
1854 } else if (inheritFromParent_
) {
1855 return parent_
->isImplicitNoneExternal();
1857 return false; // default if not specified
1861 const DeclTypeSpec
*ImplicitRules::GetType(
1862 SourceName name
, bool respectImplicitNoneType
) const {
1863 char ch
{name
.begin()[0]};
1864 if (isImplicitNoneType_
&& respectImplicitNoneType
) {
1866 } else if (auto it
{map_
.find(ch
)}; it
!= map_
.end()) {
1867 return &*it
->second
;
1868 } else if (inheritFromParent_
) {
1869 return parent_
->GetType(name
, respectImplicitNoneType
);
1870 } else if (ch
>= 'i' && ch
<= 'n') {
1871 return &context_
.MakeNumericType(TypeCategory::Integer
);
1872 } else if (ch
>= 'a' && ch
<= 'z') {
1873 return &context_
.MakeNumericType(TypeCategory::Real
);
1879 void ImplicitRules::SetTypeMapping(const DeclTypeSpec
&type
,
1880 parser::Location fromLetter
, parser::Location toLetter
) {
1881 for (char ch
= *fromLetter
; ch
; ch
= ImplicitRules::Incr(ch
)) {
1882 auto res
{map_
.emplace(ch
, type
)};
1884 context_
.Say(parser::CharBlock
{fromLetter
},
1885 "More than one implicit type specified for '%c'"_err_en_US
, ch
);
1887 if (ch
== *toLetter
) {
1893 // Return the next char after ch in a way that works for ASCII or EBCDIC.
1894 // Return '\0' for the char after 'z'.
1895 char ImplicitRules::Incr(char ch
) {
1908 llvm::raw_ostream
&operator<<(
1909 llvm::raw_ostream
&o
, const ImplicitRules
&implicitRules
) {
1910 o
<< "ImplicitRules:\n";
1911 for (char ch
= 'a'; ch
; ch
= ImplicitRules::Incr(ch
)) {
1912 ShowImplicitRule(o
, implicitRules
, ch
);
1914 ShowImplicitRule(o
, implicitRules
, '_');
1915 ShowImplicitRule(o
, implicitRules
, '$');
1916 ShowImplicitRule(o
, implicitRules
, '@');
1919 void ShowImplicitRule(
1920 llvm::raw_ostream
&o
, const ImplicitRules
&implicitRules
, char ch
) {
1921 auto it
{implicitRules
.map_
.find(ch
)};
1922 if (it
!= implicitRules
.map_
.end()) {
1923 o
<< " " << ch
<< ": " << *it
->second
<< '\n';
1927 template <typename T
> void BaseVisitor::Walk(const T
&x
) {
1928 parser::Walk(x
, *this_
);
1931 void BaseVisitor::MakePlaceholder(
1932 const parser::Name
&name
, MiscDetails::Kind kind
) {
1934 name
.symbol
= &context_
->globalScope().MakeSymbol(
1935 name
.source
, Attrs
{}, MiscDetails
{kind
});
1939 // AttrsVisitor implementation
1941 bool AttrsVisitor::BeginAttrs() {
1942 CHECK(!attrs_
&& !cudaDataAttr_
);
1946 Attrs
AttrsVisitor::GetAttrs() {
1950 Attrs
AttrsVisitor::EndAttrs() {
1951 Attrs result
{GetAttrs()};
1953 cudaDataAttr_
.reset();
1954 passName_
= std::nullopt
;
1956 isCDefined_
= false;
1960 bool AttrsVisitor::SetPassNameOn(Symbol
&symbol
) {
1964 common::visit(common::visitors
{
1965 [&](ProcEntityDetails
&x
) { x
.set_passName(*passName_
); },
1966 [&](ProcBindingDetails
&x
) { x
.set_passName(*passName_
); },
1967 [](auto &) { common::die("unexpected pass name"); },
1973 void AttrsVisitor::SetBindNameOn(Symbol
&symbol
) {
1974 if ((!attrs_
|| !attrs_
->test(Attr::BIND_C
)) &&
1975 !symbol
.attrs().test(Attr::BIND_C
)) {
1978 symbol
.SetIsCDefined(isCDefined_
);
1979 std::optional
<std::string
> label
{
1980 evaluate::GetScalarConstantValue
<evaluate::Ascii
>(bindName_
)};
1981 // 18.9.2(2): discard leading and trailing blanks
1983 symbol
.SetIsExplicitBindName(true);
1984 auto first
{label
->find_first_not_of(" ")};
1985 if (first
== std::string::npos
) {
1986 // Empty NAME= means no binding at all (18.10.2p2)
1989 auto last
{label
->find_last_not_of(" ")};
1990 label
= label
->substr(first
, last
- first
+ 1);
1991 } else if (symbol
.GetIsExplicitBindName()) {
1992 // don't try to override explicit binding name with default
1994 } else if (ClassifyProcedure(symbol
) == ProcedureDefinitionClass::Internal
) {
1995 // BIND(C) does not give an implicit binding label to internal procedures.
1998 label
= symbol
.name().ToString();
2000 // Checks whether a symbol has two Bind names.
2001 std::string oldBindName
;
2002 if (const auto *bindName
{symbol
.GetBindName()}) {
2003 oldBindName
= *bindName
;
2005 symbol
.SetBindName(std::move(*label
));
2006 if (!oldBindName
.empty()) {
2007 if (const std::string
* newBindName
{symbol
.GetBindName()}) {
2008 if (oldBindName
!= *newBindName
) {
2010 "The entity '%s' has multiple BIND names ('%s' and '%s')"_err_en_US
,
2011 symbol
.name(), oldBindName
, *newBindName
);
2017 void AttrsVisitor::Post(const parser::LanguageBindingSpec
&x
) {
2018 if (CheckAndSet(Attr::BIND_C
)) {
2019 if (const auto &name
{
2020 std::get
<std::optional
<parser::ScalarDefaultCharConstantExpr
>>(
2022 bindName_
= EvaluateExpr(*name
);
2024 isCDefined_
= std::get
<bool>(x
.t
);
2027 bool AttrsVisitor::Pre(const parser::IntentSpec
&x
) {
2028 CheckAndSet(IntentSpecToAttr(x
));
2031 bool AttrsVisitor::Pre(const parser::Pass
&x
) {
2032 if (CheckAndSet(Attr::PASS
)) {
2034 passName_
= x
.v
->source
;
2035 MakePlaceholder(*x
.v
, MiscDetails::Kind::PassName
);
2041 // C730, C743, C755, C778, C1543 say no attribute or prefix repetitions
2042 bool AttrsVisitor::IsDuplicateAttr(Attr attrName
) {
2044 if (attrs_
->test(attrName
)) {
2045 context().Warn(common::LanguageFeature::RedundantAttribute
,
2046 currStmtSource().value(),
2047 "Attribute '%s' cannot be used more than once"_warn_en_US
,
2048 AttrToString(attrName
));
2054 // See if attrName violates a constraint cause by a conflict. attr1 and attr2
2055 // name attributes that cannot be used on the same declaration
2056 bool AttrsVisitor::HaveAttrConflict(Attr attrName
, Attr attr1
, Attr attr2
) {
2058 if ((attrName
== attr1
&& attrs_
->test(attr2
)) ||
2059 (attrName
== attr2
&& attrs_
->test(attr1
))) {
2060 Say(currStmtSource().value(),
2061 "Attributes '%s' and '%s' conflict with each other"_err_en_US
,
2062 AttrToString(attr1
), AttrToString(attr2
));
2068 bool AttrsVisitor::IsConflictingAttr(Attr attrName
) {
2069 return HaveAttrConflict(attrName
, Attr::INTENT_IN
, Attr::INTENT_INOUT
) ||
2070 HaveAttrConflict(attrName
, Attr::INTENT_IN
, Attr::INTENT_OUT
) ||
2071 HaveAttrConflict(attrName
, Attr::INTENT_INOUT
, Attr::INTENT_OUT
) ||
2072 HaveAttrConflict(attrName
, Attr::PASS
, Attr::NOPASS
) || // C781
2073 HaveAttrConflict(attrName
, Attr::PURE
, Attr::IMPURE
) ||
2074 HaveAttrConflict(attrName
, Attr::PUBLIC
, Attr::PRIVATE
) ||
2075 HaveAttrConflict(attrName
, Attr::RECURSIVE
, Attr::NON_RECURSIVE
);
2077 bool AttrsVisitor::CheckAndSet(Attr attrName
) {
2078 if (IsConflictingAttr(attrName
) || IsDuplicateAttr(attrName
)) {
2081 attrs_
->set(attrName
);
2084 bool AttrsVisitor::Pre(const common::CUDADataAttr x
) {
2085 if (cudaDataAttr_
.value_or(x
) != x
) {
2086 Say(currStmtSource().value(),
2087 "CUDA data attributes '%s' and '%s' may not both be specified"_err_en_US
,
2088 common::EnumToString(*cudaDataAttr_
), common::EnumToString(x
));
2094 // DeclTypeSpecVisitor implementation
2096 const DeclTypeSpec
*DeclTypeSpecVisitor::GetDeclTypeSpec() {
2097 return state_
.declTypeSpec
;
2100 void DeclTypeSpecVisitor::BeginDeclTypeSpec() {
2101 CHECK(!state_
.expectDeclTypeSpec
);
2102 CHECK(!state_
.declTypeSpec
);
2103 state_
.expectDeclTypeSpec
= true;
2105 void DeclTypeSpecVisitor::EndDeclTypeSpec() {
2106 CHECK(state_
.expectDeclTypeSpec
);
2110 void DeclTypeSpecVisitor::SetDeclTypeSpecCategory(
2111 DeclTypeSpec::Category category
) {
2112 CHECK(state_
.expectDeclTypeSpec
);
2113 state_
.derived
.category
= category
;
2116 bool DeclTypeSpecVisitor::Pre(const parser::TypeGuardStmt
&) {
2117 BeginDeclTypeSpec();
2120 void DeclTypeSpecVisitor::Post(const parser::TypeGuardStmt
&) {
2124 void DeclTypeSpecVisitor::Post(const parser::TypeSpec
&typeSpec
) {
2125 // Record the resolved DeclTypeSpec in the parse tree for use by
2126 // expression semantics if the DeclTypeSpec is a valid TypeSpec.
2127 // The grammar ensures that it's an intrinsic or derived type spec,
2128 // not TYPE(*) or CLASS(*) or CLASS(T).
2129 if (const DeclTypeSpec
* spec
{state_
.declTypeSpec
}) {
2130 switch (spec
->category()) {
2131 case DeclTypeSpec::Numeric
:
2132 case DeclTypeSpec::Logical
:
2133 case DeclTypeSpec::Character
:
2134 typeSpec
.declTypeSpec
= spec
;
2136 case DeclTypeSpec::TypeDerived
:
2137 if (const DerivedTypeSpec
* derived
{spec
->AsDerived()}) {
2138 CheckForAbstractType(derived
->typeSymbol()); // C703
2139 typeSpec
.declTypeSpec
= spec
;
2148 void DeclTypeSpecVisitor::Post(
2149 const parser::IntrinsicTypeSpec::DoublePrecision
&) {
2150 MakeNumericType(TypeCategory::Real
, context().doublePrecisionKind());
2152 void DeclTypeSpecVisitor::Post(
2153 const parser::IntrinsicTypeSpec::DoubleComplex
&) {
2154 MakeNumericType(TypeCategory::Complex
, context().doublePrecisionKind());
2156 void DeclTypeSpecVisitor::MakeNumericType(TypeCategory category
, int kind
) {
2157 SetDeclTypeSpec(context().MakeNumericType(category
, kind
));
2160 void DeclTypeSpecVisitor::CheckForAbstractType(const Symbol
&typeSymbol
) {
2161 if (typeSymbol
.attrs().test(Attr::ABSTRACT
)) {
2162 Say("ABSTRACT derived type may not be used here"_err_en_US
);
2166 void DeclTypeSpecVisitor::Post(const parser::DeclarationTypeSpec::ClassStar
&) {
2167 SetDeclTypeSpec(context().globalScope().MakeClassStarType());
2169 void DeclTypeSpecVisitor::Post(const parser::DeclarationTypeSpec::TypeStar
&) {
2170 SetDeclTypeSpec(context().globalScope().MakeTypeStarType());
2173 // Check that we're expecting to see a DeclTypeSpec (and haven't seen one yet)
2174 // and save it in state_.declTypeSpec.
2175 void DeclTypeSpecVisitor::SetDeclTypeSpec(const DeclTypeSpec
&declTypeSpec
) {
2176 CHECK(state_
.expectDeclTypeSpec
);
2177 CHECK(!state_
.declTypeSpec
);
2178 state_
.declTypeSpec
= &declTypeSpec
;
2181 KindExpr
DeclTypeSpecVisitor::GetKindParamExpr(
2182 TypeCategory category
, const std::optional
<parser::KindSelector
> &kind
) {
2183 return AnalyzeKindSelector(context(), category
, kind
);
2186 // MessageHandler implementation
2188 Message
&MessageHandler::Say(MessageFixedText
&&msg
) {
2189 return context_
->Say(currStmtSource().value(), std::move(msg
));
2191 Message
&MessageHandler::Say(MessageFormattedText
&&msg
) {
2192 return context_
->Say(currStmtSource().value(), std::move(msg
));
2194 Message
&MessageHandler::Say(const SourceName
&name
, MessageFixedText
&&msg
) {
2195 return Say(name
, std::move(msg
), name
);
2198 // ImplicitRulesVisitor implementation
2200 void ImplicitRulesVisitor::Post(const parser::ParameterStmt
&) {
2201 prevParameterStmt_
= currStmtSource();
2204 bool ImplicitRulesVisitor::Pre(const parser::ImplicitStmt
&x
) {
2206 common::visit(common::visitors
{
2207 [&](const std::list
<ImplicitNoneNameSpec
> &y
) {
2208 return HandleImplicitNone(y
);
2210 [&](const std::list
<parser::ImplicitSpec
> &) {
2211 if (prevImplicitNoneType_
) {
2212 Say("IMPLICIT statement after IMPLICIT NONE or "
2213 "IMPLICIT NONE(TYPE) statement"_err_en_US
);
2216 implicitRules_
->set_isImplicitNoneType(false);
2221 prevImplicit_
= currStmtSource();
2225 bool ImplicitRulesVisitor::Pre(const parser::LetterSpec
&x
) {
2226 auto loLoc
{std::get
<parser::Location
>(x
.t
)};
2228 if (auto hiLocOpt
{std::get
<std::optional
<parser::Location
>>(x
.t
)}) {
2230 if (*hiLoc
< *loLoc
) {
2231 Say(hiLoc
, "'%s' does not follow '%s' alphabetically"_err_en_US
,
2232 std::string(hiLoc
, 1), std::string(loLoc
, 1));
2236 implicitRules_
->SetTypeMapping(*GetDeclTypeSpec(), loLoc
, hiLoc
);
2240 bool ImplicitRulesVisitor::Pre(const parser::ImplicitSpec
&) {
2241 BeginDeclTypeSpec();
2242 set_allowForwardReferenceToDerivedType(true);
2246 void ImplicitRulesVisitor::Post(const parser::ImplicitSpec
&) {
2247 set_allowForwardReferenceToDerivedType(false);
2251 void ImplicitRulesVisitor::SetScope(const Scope
&scope
) {
2252 implicitRules_
= &DEREF(implicitRulesMap_
).at(&scope
);
2253 prevImplicit_
= std::nullopt
;
2254 prevImplicitNone_
= std::nullopt
;
2255 prevImplicitNoneType_
= std::nullopt
;
2256 prevParameterStmt_
= std::nullopt
;
2258 void ImplicitRulesVisitor::BeginScope(const Scope
&scope
) {
2259 // find or create implicit rules for this scope
2260 DEREF(implicitRulesMap_
).try_emplace(&scope
, context(), implicitRules_
);
2264 // TODO: for all of these errors, reference previous statement too
2265 bool ImplicitRulesVisitor::HandleImplicitNone(
2266 const std::list
<ImplicitNoneNameSpec
> &nameSpecs
) {
2267 if (prevImplicitNone_
) {
2268 Say("More than one IMPLICIT NONE statement"_err_en_US
);
2269 Say(*prevImplicitNone_
, "Previous IMPLICIT NONE statement"_en_US
);
2272 if (prevParameterStmt_
) {
2273 Say("IMPLICIT NONE statement after PARAMETER statement"_err_en_US
);
2276 prevImplicitNone_
= currStmtSource();
2277 bool implicitNoneTypeNever
{
2278 context().IsEnabled(common::LanguageFeature::ImplicitNoneTypeNever
)};
2279 if (nameSpecs
.empty()) {
2280 if (!implicitNoneTypeNever
) {
2281 prevImplicitNoneType_
= currStmtSource();
2282 implicitRules_
->set_isImplicitNoneType(true);
2283 if (prevImplicit_
) {
2284 Say("IMPLICIT NONE statement after IMPLICIT statement"_err_en_US
);
2291 for (const auto noneSpec
: nameSpecs
) {
2293 case ImplicitNoneNameSpec::External
:
2294 implicitRules_
->set_isImplicitNoneExternal(true);
2297 case ImplicitNoneNameSpec::Type
:
2298 if (!implicitNoneTypeNever
) {
2299 prevImplicitNoneType_
= currStmtSource();
2300 implicitRules_
->set_isImplicitNoneType(true);
2301 if (prevImplicit_
) {
2302 Say("IMPLICIT NONE(TYPE) after IMPLICIT statement"_err_en_US
);
2311 Say("TYPE specified more than once in IMPLICIT NONE statement"_err_en_US
);
2314 if (sawExternal
> 1) {
2315 Say("EXTERNAL specified more than once in IMPLICIT NONE statement"_err_en_US
);
2322 // ArraySpecVisitor implementation
2324 void ArraySpecVisitor::Post(const parser::ArraySpec
&x
) {
2325 CHECK(arraySpec_
.empty());
2326 arraySpec_
= AnalyzeArraySpec(context(), x
);
2328 void ArraySpecVisitor::Post(const parser::ComponentArraySpec
&x
) {
2329 CHECK(arraySpec_
.empty());
2330 arraySpec_
= AnalyzeArraySpec(context(), x
);
2332 void ArraySpecVisitor::Post(const parser::CoarraySpec
&x
) {
2333 CHECK(coarraySpec_
.empty());
2334 coarraySpec_
= AnalyzeCoarraySpec(context(), x
);
2337 const ArraySpec
&ArraySpecVisitor::arraySpec() {
2338 return !arraySpec_
.empty() ? arraySpec_
: attrArraySpec_
;
2340 const ArraySpec
&ArraySpecVisitor::coarraySpec() {
2341 return !coarraySpec_
.empty() ? coarraySpec_
: attrCoarraySpec_
;
2343 void ArraySpecVisitor::BeginArraySpec() {
2344 CHECK(arraySpec_
.empty());
2345 CHECK(coarraySpec_
.empty());
2346 CHECK(attrArraySpec_
.empty());
2347 CHECK(attrCoarraySpec_
.empty());
2349 void ArraySpecVisitor::EndArraySpec() {
2350 CHECK(arraySpec_
.empty());
2351 CHECK(coarraySpec_
.empty());
2352 attrArraySpec_
.clear();
2353 attrCoarraySpec_
.clear();
2355 void ArraySpecVisitor::PostAttrSpec() {
2356 // Save dimension/codimension from attrs so we can process array/coarray-spec
2357 // on the entity-decl
2358 if (!arraySpec_
.empty()) {
2359 if (attrArraySpec_
.empty()) {
2360 attrArraySpec_
= arraySpec_
;
2363 Say(currStmtSource().value(),
2364 "Attribute 'DIMENSION' cannot be used more than once"_err_en_US
);
2367 if (!coarraySpec_
.empty()) {
2368 if (attrCoarraySpec_
.empty()) {
2369 attrCoarraySpec_
= coarraySpec_
;
2370 coarraySpec_
.clear();
2372 Say(currStmtSource().value(),
2373 "Attribute 'CODIMENSION' cannot be used more than once"_err_en_US
);
2378 // FuncResultStack implementation
2380 FuncResultStack::~FuncResultStack() { CHECK(stack_
.empty()); }
2382 void FuncResultStack::CompleteFunctionResultType() {
2383 // If the function has a type in the prefix, process it now.
2384 FuncInfo
*info
{Top()};
2385 if (info
&& &info
->scope
== &scopeHandler_
.currScope()) {
2386 if (info
->parsedType
&& info
->resultSymbol
) {
2387 scopeHandler_
.messageHandler().set_currStmtSource(info
->source
);
2388 if (const auto *type
{
2389 scopeHandler_
.ProcessTypeSpec(*info
->parsedType
, true)}) {
2390 Symbol
&symbol
{*info
->resultSymbol
};
2391 if (!scopeHandler_
.context().HasError(symbol
)) {
2392 if (symbol
.GetType()) {
2393 scopeHandler_
.Say(symbol
.name(),
2394 "Function cannot have both an explicit type prefix and a RESULT suffix"_err_en_US
);
2395 scopeHandler_
.context().SetError(symbol
);
2397 symbol
.SetType(*type
);
2401 info
->parsedType
= nullptr;
2406 // Called from ConvertTo{Object/Proc}Entity to cope with any appearance
2407 // of the function result in a specification expression.
2408 void FuncResultStack::CompleteTypeIfFunctionResult(Symbol
&symbol
) {
2409 if (FuncInfo
* info
{Top()}) {
2410 if (info
->resultSymbol
== &symbol
) {
2411 CompleteFunctionResultType();
2416 void FuncResultStack::Pop() {
2417 if (!stack_
.empty() && &stack_
.back().scope
== &scopeHandler_
.currScope()) {
2422 // ScopeHandler implementation
2424 void ScopeHandler::SayAlreadyDeclared(const parser::Name
&name
, Symbol
&prev
) {
2425 SayAlreadyDeclared(name
.source
, prev
);
2427 void ScopeHandler::SayAlreadyDeclared(const SourceName
&name
, Symbol
&prev
) {
2428 if (context().HasError(prev
)) {
2429 // don't report another error about prev
2431 if (const auto *details
{prev
.detailsIf
<UseDetails
>()}) {
2432 Say(name
, "'%s' is already declared in this scoping unit"_err_en_US
)
2433 .Attach(details
->location(),
2434 "It is use-associated with '%s' in module '%s'"_en_US
,
2435 details
->symbol().name(), GetUsedModule(*details
).name());
2437 SayAlreadyDeclared(name
, prev
.name());
2439 context().SetError(prev
);
2442 void ScopeHandler::SayAlreadyDeclared(
2443 const SourceName
&name1
, const SourceName
&name2
) {
2444 if (name1
.begin() < name2
.begin()) {
2445 SayAlreadyDeclared(name2
, name1
);
2447 Say(name1
, "'%s' is already declared in this scoping unit"_err_en_US
)
2448 .Attach(name2
, "Previous declaration of '%s'"_en_US
, name2
);
2452 void ScopeHandler::SayWithReason(const parser::Name
&name
, Symbol
&symbol
,
2453 MessageFixedText
&&msg1
, Message
&&msg2
) {
2454 bool isFatal
{msg1
.IsFatal()};
2455 Say(name
, std::move(msg1
), symbol
.name()).Attach(std::move(msg2
));
2456 context().SetError(symbol
, isFatal
);
2459 template <typename
... A
>
2460 Message
&ScopeHandler::SayWithDecl(const parser::Name
&name
, Symbol
&symbol
,
2461 MessageFixedText
&&msg
, A
&&...args
) {
2463 Say(name
.source
, std::move(msg
), symbol
.name(), std::forward
<A
>(args
)...)
2464 .Attach(symbol
.name(),
2465 symbol
.test(Symbol::Flag::Implicit
)
2466 ? "Implicit declaration of '%s'"_en_US
2467 : "Declaration of '%s'"_en_US
,
2469 if (const auto *proc
{symbol
.detailsIf
<ProcEntityDetails
>()}) {
2470 if (auto usedAsProc
{proc
->usedAsProcedureHere()}) {
2471 if (usedAsProc
->begin() != symbol
.name().begin()) {
2472 message
.Attach(*usedAsProc
, "Referenced as a procedure"_en_US
);
2479 void ScopeHandler::SayLocalMustBeVariable(
2480 const parser::Name
&name
, Symbol
&symbol
) {
2481 SayWithDecl(name
, symbol
,
2482 "The name '%s' must be a variable to appear"
2483 " in a locality-spec"_err_en_US
);
2486 Message
&ScopeHandler::SayDerivedType(
2487 const SourceName
&name
, MessageFixedText
&&msg
, const Scope
&type
) {
2488 const Symbol
&typeSymbol
{DEREF(type
.GetSymbol())};
2489 return Say(name
, std::move(msg
), name
, typeSymbol
.name())
2490 .Attach(typeSymbol
.name(), "Declaration of derived type '%s'"_en_US
,
2493 Message
&ScopeHandler::Say2(const SourceName
&name1
, MessageFixedText
&&msg1
,
2494 const SourceName
&name2
, MessageFixedText
&&msg2
) {
2495 return Say(name1
, std::move(msg1
)).Attach(name2
, std::move(msg2
), name2
);
2497 Message
&ScopeHandler::Say2(const SourceName
&name
, MessageFixedText
&&msg1
,
2498 Symbol
&symbol
, MessageFixedText
&&msg2
) {
2499 bool isFatal
{msg1
.IsFatal()};
2500 Message
&result
{Say2(name
, std::move(msg1
), symbol
.name(), std::move(msg2
))};
2501 context().SetError(symbol
, isFatal
);
2504 Message
&ScopeHandler::Say2(const parser::Name
&name
, MessageFixedText
&&msg1
,
2505 Symbol
&symbol
, MessageFixedText
&&msg2
) {
2506 bool isFatal
{msg1
.IsFatal()};
2508 Say2(name
.source
, std::move(msg1
), symbol
.name(), std::move(msg2
))};
2509 context().SetError(symbol
, isFatal
);
2513 // This is essentially GetProgramUnitContaining(), but it can return
2514 // a mutable Scope &, it ignores statement functions, and it fails
2515 // gracefully for error recovery (returning the original Scope).
2516 template <typename T
> static T
&GetInclusiveScope(T
&scope
) {
2517 for (T
*s
{&scope
}; !s
->IsGlobal(); s
= &s
->parent()) {
2518 switch (s
->kind()) {
2519 case Scope::Kind::Module
:
2520 case Scope::Kind::MainProgram
:
2521 case Scope::Kind::Subprogram
:
2522 case Scope::Kind::BlockData
:
2523 if (!s
->IsStmtFunction()) {
2533 Scope
&ScopeHandler::InclusiveScope() { return GetInclusiveScope(currScope()); }
2535 Scope
*ScopeHandler::GetHostProcedure() {
2536 Scope
&parent
{InclusiveScope().parent()};
2537 switch (parent
.kind()) {
2538 case Scope::Kind::Subprogram
:
2540 case Scope::Kind::MainProgram
:
2547 Scope
&ScopeHandler::NonDerivedTypeScope() {
2548 return currScope_
->IsDerivedType() ? currScope_
->parent() : *currScope_
;
2551 void ScopeHandler::PushScope(Scope::Kind kind
, Symbol
*symbol
) {
2552 PushScope(currScope().MakeScope(kind
, symbol
));
2554 void ScopeHandler::PushScope(Scope
&scope
) {
2555 currScope_
= &scope
;
2556 auto kind
{currScope_
->kind()};
2557 if (kind
!= Scope::Kind::BlockConstruct
&&
2558 kind
!= Scope::Kind::OtherConstruct
&& kind
!= Scope::Kind::OtherClause
) {
2561 // The name of a module or submodule cannot be "used" in its scope,
2562 // as we read 19.3.1(2), so we allow the name to be used as a local
2563 // identifier in the module or submodule too. Same with programs
2564 // (14.1(3)) and BLOCK DATA.
2565 if (!currScope_
->IsDerivedType() && kind
!= Scope::Kind::Module
&&
2566 kind
!= Scope::Kind::MainProgram
&& kind
!= Scope::Kind::BlockData
) {
2567 if (auto *symbol
{scope
.symbol()}) {
2568 // Create a dummy symbol so we can't create another one with the same
2569 // name. It might already be there if we previously pushed the scope.
2570 SourceName name
{symbol
->name()};
2571 if (!FindInScope(scope
, name
)) {
2572 auto &newSymbol
{MakeSymbol(name
)};
2573 if (kind
== Scope::Kind::Subprogram
) {
2574 // Allow for recursive references. If this symbol is a function
2575 // without an explicit RESULT(), this new symbol will be discarded
2576 // and replaced with an object of the same name.
2577 newSymbol
.set_details(HostAssocDetails
{*symbol
});
2579 newSymbol
.set_details(MiscDetails
{MiscDetails::Kind::ScopeName
});
2585 void ScopeHandler::PopScope() {
2586 CHECK(currScope_
&& !currScope_
->IsGlobal());
2587 // Entities that are not yet classified as objects or procedures are now
2588 // assumed to be objects.
2589 // TODO: Statement functions
2590 for (auto &pair
: currScope()) {
2591 ConvertToObjectEntity(*pair
.second
);
2593 funcResultStack_
.Pop();
2594 // If popping back into a global scope, pop back to the top scope.
2595 Scope
*hermetic
{context().currentHermeticModuleFileScope()};
2596 SetScope(currScope_
->parent().IsGlobal()
2597 ? (hermetic
? *hermetic
: context().globalScope())
2598 : currScope_
->parent());
2600 void ScopeHandler::SetScope(Scope
&scope
) {
2601 currScope_
= &scope
;
2602 ImplicitRulesVisitor::SetScope(InclusiveScope());
2605 Symbol
*ScopeHandler::FindSymbol(const parser::Name
&name
) {
2606 return FindSymbol(currScope(), name
);
2608 Symbol
*ScopeHandler::FindSymbol(const Scope
&scope
, const parser::Name
&name
) {
2609 if (scope
.IsDerivedType()) {
2610 if (Symbol
* symbol
{scope
.FindComponent(name
.source
)}) {
2611 if (symbol
->has
<TypeParamDetails
>()) {
2612 return Resolve(name
, symbol
);
2615 return FindSymbol(scope
.parent(), name
);
2617 // In EQUIVALENCE statements only resolve names in the local scope, see
2618 // 19.5.1.4, paragraph 2, item (10)
2619 return Resolve(name
,
2620 inEquivalenceStmt_
? FindInScope(scope
, name
)
2621 : scope
.FindSymbol(name
.source
));
2625 Symbol
&ScopeHandler::MakeSymbol(
2626 Scope
&scope
, const SourceName
&name
, Attrs attrs
) {
2627 if (Symbol
* symbol
{FindInScope(scope
, name
)}) {
2628 CheckDuplicatedAttrs(name
, *symbol
, attrs
);
2629 SetExplicitAttrs(*symbol
, attrs
);
2632 const auto pair
{scope
.try_emplace(name
, attrs
, UnknownDetails
{})};
2633 CHECK(pair
.second
); // name was not found, so must be able to add
2634 return *pair
.first
->second
;
2637 Symbol
&ScopeHandler::MakeSymbol(const SourceName
&name
, Attrs attrs
) {
2638 return MakeSymbol(currScope(), name
, attrs
);
2640 Symbol
&ScopeHandler::MakeSymbol(const parser::Name
&name
, Attrs attrs
) {
2641 return Resolve(name
, MakeSymbol(name
.source
, attrs
));
2643 Symbol
&ScopeHandler::MakeHostAssocSymbol(
2644 const parser::Name
&name
, const Symbol
&hostSymbol
) {
2645 Symbol
&symbol
{*NonDerivedTypeScope()
2646 .try_emplace(name
.source
, HostAssocDetails
{hostSymbol
})
2648 name
.symbol
= &symbol
;
2649 symbol
.attrs() = hostSymbol
.attrs(); // TODO: except PRIVATE, PUBLIC?
2650 // These attributes can be redundantly reapplied without error
2651 // on the host-associated name, at most once (C815).
2652 symbol
.implicitAttrs() =
2653 symbol
.attrs() & Attrs
{Attr::ASYNCHRONOUS
, Attr::VOLATILE
};
2654 // SAVE statement in the inner scope will create a new symbol.
2655 // If the host variable is used via host association,
2656 // we have to propagate whether SAVE is implicit in the host scope.
2657 // Otherwise, verifications that do not allow explicit SAVE
2658 // attribute would fail.
2659 symbol
.implicitAttrs() |= hostSymbol
.implicitAttrs() & Attrs
{Attr::SAVE
};
2660 symbol
.flags() = hostSymbol
.flags();
2663 Symbol
&ScopeHandler::CopySymbol(const SourceName
&name
, const Symbol
&symbol
) {
2664 CHECK(!FindInScope(name
));
2665 return MakeSymbol(currScope(), name
, symbol
.attrs());
2668 // Look for name only in scope, not in enclosing scopes.
2670 Symbol
*ScopeHandler::FindInScope(
2671 const Scope
&scope
, const parser::Name
&name
) {
2672 return Resolve(name
, FindInScope(scope
, name
.source
));
2674 Symbol
*ScopeHandler::FindInScope(const Scope
&scope
, const SourceName
&name
) {
2675 // all variants of names, e.g. "operator(.ne.)" for "operator(/=)"
2676 for (const std::string
&n
: GetAllNames(context(), name
)) {
2677 auto it
{scope
.find(SourceName
{n
})};
2678 if (it
!= scope
.end()) {
2679 return &*it
->second
;
2685 // Find a component or type parameter by name in a derived type or its parents.
2686 Symbol
*ScopeHandler::FindInTypeOrParents(
2687 const Scope
&scope
, const parser::Name
&name
) {
2688 return Resolve(name
, scope
.FindComponent(name
.source
));
2690 Symbol
*ScopeHandler::FindInTypeOrParents(const parser::Name
&name
) {
2691 return FindInTypeOrParents(currScope(), name
);
2693 Symbol
*ScopeHandler::FindInScopeOrBlockConstructs(
2694 const Scope
&scope
, SourceName name
) {
2695 if (Symbol
* symbol
{FindInScope(scope
, name
)}) {
2698 for (const Scope
&child
: scope
.children()) {
2699 if (child
.kind() == Scope::Kind::BlockConstruct
) {
2700 if (Symbol
* symbol
{FindInScopeOrBlockConstructs(child
, name
)}) {
2708 void ScopeHandler::EraseSymbol(const parser::Name
&name
) {
2709 currScope().erase(name
.source
);
2710 name
.symbol
= nullptr;
2713 static bool NeedsType(const Symbol
&symbol
) {
2714 return !symbol
.GetType() &&
2715 common::visit(common::visitors
{
2716 [](const EntityDetails
&) { return true; },
2717 [](const ObjectEntityDetails
&) { return true; },
2718 [](const AssocEntityDetails
&) { return true; },
2719 [&](const ProcEntityDetails
&p
) {
2720 return symbol
.test(Symbol::Flag::Function
) &&
2721 !symbol
.attrs().test(Attr::INTRINSIC
) &&
2722 !p
.type() && !p
.procInterface();
2724 [](const auto &) { return false; },
2729 void ScopeHandler::ApplyImplicitRules(
2730 Symbol
&symbol
, bool allowForwardReference
) {
2731 funcResultStack_
.CompleteTypeIfFunctionResult(symbol
);
2732 if (context().HasError(symbol
) || !NeedsType(symbol
)) {
2735 if (const DeclTypeSpec
* type
{GetImplicitType(symbol
)}) {
2736 if (!skipImplicitTyping_
) {
2737 symbol
.set(Symbol::Flag::Implicit
);
2738 symbol
.SetType(*type
);
2742 if (symbol
.has
<ProcEntityDetails
>() && !symbol
.attrs().test(Attr::EXTERNAL
)) {
2743 std::optional
<Symbol::Flag
> functionOrSubroutineFlag
;
2744 if (symbol
.test(Symbol::Flag::Function
)) {
2745 functionOrSubroutineFlag
= Symbol::Flag::Function
;
2746 } else if (symbol
.test(Symbol::Flag::Subroutine
)) {
2747 functionOrSubroutineFlag
= Symbol::Flag::Subroutine
;
2749 if (IsIntrinsic(symbol
.name(), functionOrSubroutineFlag
)) {
2750 // type will be determined in expression semantics
2751 AcquireIntrinsicProcedureFlags(symbol
);
2755 if (allowForwardReference
&& ImplicitlyTypeForwardRef(symbol
)) {
2758 if (const auto *entity
{symbol
.detailsIf
<EntityDetails
>()};
2759 entity
&& entity
->isDummy()) {
2760 // Dummy argument, no declaration or reference; if it turns
2761 // out to be a subroutine, it's fine, and if it is a function
2762 // or object, it'll be caught later.
2765 if (deferImplicitTyping_
) {
2768 if (!context().HasError(symbol
)) {
2769 Say(symbol
.name(), "No explicit type declared for '%s'"_err_en_US
);
2770 context().SetError(symbol
);
2774 // Extension: Allow forward references to scalar integer dummy arguments
2775 // or variables in COMMON to appear in specification expressions under
2776 // IMPLICIT NONE(TYPE) when what would otherwise have been their implicit
2777 // type is default INTEGER.
2778 bool ScopeHandler::ImplicitlyTypeForwardRef(Symbol
&symbol
) {
2779 if (!inSpecificationPart_
|| context().HasError(symbol
) ||
2780 !(IsDummy(symbol
) || FindCommonBlockContaining(symbol
)) ||
2781 symbol
.Rank() != 0 ||
2782 !context().languageFeatures().IsEnabled(
2783 common::LanguageFeature::ForwardRefImplicitNone
)) {
2786 const DeclTypeSpec
*type
{
2787 GetImplicitType(symbol
, false /*ignore IMPLICIT NONE*/)};
2788 if (!type
|| !type
->IsNumeric(TypeCategory::Integer
)) {
2791 auto kind
{evaluate::ToInt64(type
->numericTypeSpec().kind())};
2792 if (!kind
|| *kind
!= context().GetDefaultKind(TypeCategory::Integer
)) {
2795 if (!ConvertToObjectEntity(symbol
)) {
2798 // TODO: check no INTENT(OUT) if dummy?
2799 context().Warn(common::LanguageFeature::ForwardRefImplicitNone
, symbol
.name(),
2800 "'%s' was used without (or before) being explicitly typed"_warn_en_US
,
2802 symbol
.set(Symbol::Flag::Implicit
);
2803 symbol
.SetType(*type
);
2807 // Ensure that the symbol for an intrinsic procedure is marked with
2808 // the INTRINSIC attribute. Also set PURE &/or ELEMENTAL as
2810 void ScopeHandler::AcquireIntrinsicProcedureFlags(Symbol
&symbol
) {
2811 SetImplicitAttr(symbol
, Attr::INTRINSIC
);
2812 switch (context().intrinsics().GetIntrinsicClass(symbol
.name().ToString())) {
2813 case evaluate::IntrinsicClass::elementalFunction
:
2814 case evaluate::IntrinsicClass::elementalSubroutine
:
2815 SetExplicitAttr(symbol
, Attr::ELEMENTAL
);
2816 SetExplicitAttr(symbol
, Attr::PURE
);
2818 case evaluate::IntrinsicClass::impureSubroutine
:
2821 SetExplicitAttr(symbol
, Attr::PURE
);
2825 const DeclTypeSpec
*ScopeHandler::GetImplicitType(
2826 Symbol
&symbol
, bool respectImplicitNoneType
) {
2827 const Scope
*scope
{&symbol
.owner()};
2828 if (scope
->IsGlobal()) {
2829 scope
= &currScope();
2831 scope
= &GetInclusiveScope(*scope
);
2832 const auto *type
{implicitRulesMap_
->at(scope
).GetType(
2833 symbol
.name(), respectImplicitNoneType
)};
2835 if (const DerivedTypeSpec
* derived
{type
->AsDerived()}) {
2836 // Resolve any forward-referenced derived type; a quick no-op else.
2837 auto &instantiatable
{*const_cast<DerivedTypeSpec
*>(derived
)};
2838 instantiatable
.Instantiate(currScope());
2844 void ScopeHandler::CheckEntryDummyUse(SourceName source
, Symbol
*symbol
) {
2845 if (!inSpecificationPart_
&& symbol
&&
2846 symbol
->test(Symbol::Flag::EntryDummyArgument
)) {
2848 "Dummy argument '%s' may not be used before its ENTRY statement"_err_en_US
,
2850 symbol
->set(Symbol::Flag::EntryDummyArgument
, false);
2854 // Convert symbol to be a ObjectEntity or return false if it can't be.
2855 bool ScopeHandler::ConvertToObjectEntity(Symbol
&symbol
) {
2856 if (symbol
.has
<ObjectEntityDetails
>()) {
2858 } else if (symbol
.has
<UnknownDetails
>()) {
2859 // These are attributes that a name could have picked up from
2860 // an attribute statement or type declaration statement.
2861 if (symbol
.attrs().HasAny({Attr::EXTERNAL
, Attr::INTRINSIC
})) {
2864 symbol
.set_details(ObjectEntityDetails
{});
2865 } else if (auto *details
{symbol
.detailsIf
<EntityDetails
>()}) {
2866 if (symbol
.attrs().HasAny({Attr::EXTERNAL
, Attr::INTRINSIC
})) {
2869 funcResultStack_
.CompleteTypeIfFunctionResult(symbol
);
2870 symbol
.set_details(ObjectEntityDetails
{std::move(*details
)});
2871 } else if (auto *useDetails
{symbol
.detailsIf
<UseDetails
>()}) {
2872 return useDetails
->symbol().has
<ObjectEntityDetails
>();
2873 } else if (auto *hostDetails
{symbol
.detailsIf
<HostAssocDetails
>()}) {
2874 return hostDetails
->symbol().has
<ObjectEntityDetails
>();
2880 // Convert symbol to be a ProcEntity or return false if it can't be.
2881 bool ScopeHandler::ConvertToProcEntity(
2882 Symbol
&symbol
, std::optional
<SourceName
> usedHere
) {
2883 if (symbol
.has
<ProcEntityDetails
>()) {
2884 } else if (symbol
.has
<UnknownDetails
>()) {
2885 symbol
.set_details(ProcEntityDetails
{});
2886 } else if (auto *details
{symbol
.detailsIf
<EntityDetails
>()}) {
2887 if (IsFunctionResult(symbol
) &&
2888 !(IsPointer(symbol
) && symbol
.attrs().test(Attr::EXTERNAL
))) {
2889 // Don't turn function result into a procedure pointer unless both
2890 // POINTER and EXTERNAL
2893 funcResultStack_
.CompleteTypeIfFunctionResult(symbol
);
2894 symbol
.set_details(ProcEntityDetails
{std::move(*details
)});
2895 if (symbol
.GetType() && !symbol
.test(Symbol::Flag::Implicit
)) {
2896 CHECK(!symbol
.test(Symbol::Flag::Subroutine
));
2897 symbol
.set(Symbol::Flag::Function
);
2899 } else if (auto *useDetails
{symbol
.detailsIf
<UseDetails
>()}) {
2900 return useDetails
->symbol().has
<ProcEntityDetails
>();
2901 } else if (auto *hostDetails
{symbol
.detailsIf
<HostAssocDetails
>()}) {
2902 return hostDetails
->symbol().has
<ProcEntityDetails
>();
2906 auto &proc
{symbol
.get
<ProcEntityDetails
>()};
2907 if (usedHere
&& !proc
.usedAsProcedureHere()) {
2908 proc
.set_usedAsProcedureHere(*usedHere
);
2913 const DeclTypeSpec
&ScopeHandler::MakeNumericType(
2914 TypeCategory category
, const std::optional
<parser::KindSelector
> &kind
) {
2915 KindExpr value
{GetKindParamExpr(category
, kind
)};
2916 if (auto known
{evaluate::ToInt64(value
)}) {
2917 return MakeNumericType(category
, static_cast<int>(*known
));
2919 return currScope_
->MakeNumericType(category
, std::move(value
));
2923 const DeclTypeSpec
&ScopeHandler::MakeNumericType(
2924 TypeCategory category
, int kind
) {
2925 return context().MakeNumericType(category
, kind
);
2928 const DeclTypeSpec
&ScopeHandler::MakeLogicalType(
2929 const std::optional
<parser::KindSelector
> &kind
) {
2930 KindExpr value
{GetKindParamExpr(TypeCategory::Logical
, kind
)};
2931 if (auto known
{evaluate::ToInt64(value
)}) {
2932 return MakeLogicalType(static_cast<int>(*known
));
2934 return currScope_
->MakeLogicalType(std::move(value
));
2938 const DeclTypeSpec
&ScopeHandler::MakeLogicalType(int kind
) {
2939 return context().MakeLogicalType(kind
);
2942 void ScopeHandler::NotePossibleBadForwardRef(const parser::Name
&name
) {
2943 if (inSpecificationPart_
&& !deferImplicitTyping_
&& name
.symbol
) {
2944 auto kind
{currScope().kind()};
2945 if ((kind
== Scope::Kind::Subprogram
&& !currScope().IsStmtFunction()) ||
2946 kind
== Scope::Kind::BlockConstruct
) {
2947 bool isHostAssociated
{&name
.symbol
->owner() == &currScope()
2948 ? name
.symbol
->has
<HostAssocDetails
>()
2949 : name
.symbol
->owner().Contains(currScope())};
2950 if (isHostAssociated
) {
2951 specPartState_
.forwardRefs
.insert(name
.source
);
2957 std::optional
<SourceName
> ScopeHandler::HadForwardRef(
2958 const Symbol
&symbol
) const {
2959 auto iter
{specPartState_
.forwardRefs
.find(symbol
.name())};
2960 if (iter
!= specPartState_
.forwardRefs
.end()) {
2963 return std::nullopt
;
2966 bool ScopeHandler::CheckPossibleBadForwardRef(const Symbol
&symbol
) {
2967 if (!context().HasError(symbol
)) {
2968 if (auto fwdRef
{HadForwardRef(symbol
)}) {
2969 const Symbol
*outer
{symbol
.owner().FindSymbol(symbol
.name())};
2970 if (outer
&& symbol
.has
<UseDetails
>() &&
2971 &symbol
.GetUltimate() == &outer
->GetUltimate()) {
2972 // e.g. IMPORT of host's USE association
2976 "Forward reference to '%s' is not allowed in the same specification part"_err_en_US
,
2978 .Attach(symbol
.name(), "Later declaration of '%s'"_en_US
, *fwdRef
);
2979 context().SetError(symbol
);
2982 if ((IsDummy(symbol
) || FindCommonBlockContaining(symbol
)) &&
2983 isImplicitNoneType() && symbol
.test(Symbol::Flag::Implicit
) &&
2984 !context().HasError(symbol
)) {
2985 // Dummy or COMMON was implicitly typed despite IMPLICIT NONE(TYPE) in
2986 // ApplyImplicitRules() due to use in a specification expression,
2987 // and no explicit type declaration appeared later.
2988 Say(symbol
.name(), "No explicit type declared for '%s'"_err_en_US
);
2989 context().SetError(symbol
);
2996 void ScopeHandler::MakeExternal(Symbol
&symbol
) {
2997 if (!symbol
.attrs().test(Attr::EXTERNAL
)) {
2998 SetImplicitAttr(symbol
, Attr::EXTERNAL
);
2999 if (symbol
.attrs().test(Attr::INTRINSIC
)) { // C840
3001 "Symbol '%s' cannot have both EXTERNAL and INTRINSIC attributes"_err_en_US
,
3007 bool ScopeHandler::CheckDuplicatedAttr(
3008 SourceName name
, Symbol
&symbol
, Attr attr
) {
3009 if (attr
== Attr::SAVE
) {
3010 // checked elsewhere
3011 } else if (symbol
.attrs().test(attr
)) { // C815
3012 if (symbol
.implicitAttrs().test(attr
)) {
3013 // Implied attribute is now confirmed explicitly
3014 symbol
.implicitAttrs().reset(attr
);
3016 Say(name
, "%s attribute was already specified on '%s'"_err_en_US
,
3017 EnumToString(attr
), name
);
3024 bool ScopeHandler::CheckDuplicatedAttrs(
3025 SourceName name
, Symbol
&symbol
, Attrs attrs
) {
3027 attrs
.IterateOverMembers(
3028 [&](Attr x
) { ok
&= CheckDuplicatedAttr(name
, symbol
, x
); });
3032 void ScopeHandler::SetCUDADataAttr(SourceName source
, Symbol
&symbol
,
3033 std::optional
<common::CUDADataAttr
> attr
) {
3035 ConvertToObjectEntity(symbol
);
3036 if (auto *object
{symbol
.detailsIf
<ObjectEntityDetails
>()}) {
3037 if (*attr
!= object
->cudaDataAttr().value_or(*attr
)) {
3039 "'%s' already has another CUDA data attribute ('%s')"_err_en_US
,
3041 std::string
{common::EnumToString(*object
->cudaDataAttr())}.c_str());
3043 object
->set_cudaDataAttr(attr
);
3047 "'%s' is not an object and may not have a CUDA data attribute"_err_en_US
,
3053 // ModuleVisitor implementation
3055 bool ModuleVisitor::Pre(const parser::Only
&x
) {
3056 common::visit(common::visitors
{
3057 [&](const Indirection
<parser::GenericSpec
> &generic
) {
3058 GenericSpecInfo genericSpecInfo
{generic
.value()};
3059 AddUseOnly(genericSpecInfo
.symbolName());
3060 AddUse(genericSpecInfo
);
3062 [&](const parser::Name
&name
) {
3063 AddUseOnly(name
.source
);
3064 Resolve(name
, AddUse(name
.source
, name
.source
).use
);
3066 [&](const parser::Rename
&rename
) { Walk(rename
); },
3072 void ModuleVisitor::CollectUseRenames(const parser::UseStmt
&useStmt
) {
3073 auto doRename
{[&](const parser::Rename
&rename
) {
3074 if (const auto *names
{std::get_if
<parser::Rename::Names
>(&rename
.u
)}) {
3075 AddUseRename(std::get
<1>(names
->t
).source
, useStmt
.moduleName
.source
);
3080 [&](const std::list
<parser::Rename
> &renames
) {
3081 for (const auto &rename
: renames
) {
3085 [&](const std::list
<parser::Only
> &onlys
) {
3086 for (const auto &only
: onlys
) {
3087 if (const auto *rename
{std::get_if
<parser::Rename
>(&only
.u
)}) {
3096 bool ModuleVisitor::Pre(const parser::Rename::Names
&x
) {
3097 const auto &localName
{std::get
<0>(x
.t
)};
3098 const auto &useName
{std::get
<1>(x
.t
)};
3099 SymbolRename rename
{AddUse(localName
.source
, useName
.source
)};
3100 Resolve(useName
, rename
.use
);
3101 Resolve(localName
, rename
.local
);
3104 bool ModuleVisitor::Pre(const parser::Rename::Operators
&x
) {
3105 const parser::DefinedOpName
&local
{std::get
<0>(x
.t
)};
3106 const parser::DefinedOpName
&use
{std::get
<1>(x
.t
)};
3107 GenericSpecInfo localInfo
{local
};
3108 GenericSpecInfo useInfo
{use
};
3109 if (IsIntrinsicOperator(context(), local
.v
.source
)) {
3111 "Intrinsic operator '%s' may not be used as a defined operator"_err_en_US
);
3112 } else if (IsLogicalConstant(context(), local
.v
.source
)) {
3114 "Logical constant '%s' may not be used as a defined operator"_err_en_US
);
3116 SymbolRename rename
{AddUse(localInfo
.symbolName(), useInfo
.symbolName())};
3117 useInfo
.Resolve(rename
.use
);
3118 localInfo
.Resolve(rename
.local
);
3123 // Set useModuleScope_ to the Scope of the module being used.
3124 bool ModuleVisitor::Pre(const parser::UseStmt
&x
) {
3125 std::optional
<bool> isIntrinsic
;
3127 isIntrinsic
= *x
.nature
== parser::UseStmt::ModuleNature::Intrinsic
;
3128 } else if (currScope().IsModule() && currScope().symbol() &&
3129 currScope().symbol()->attrs().test(Attr::INTRINSIC
)) {
3130 // Intrinsic modules USE only other intrinsic modules
3133 useModuleScope_
= FindModule(x
.moduleName
, isIntrinsic
);
3134 if (!useModuleScope_
) {
3137 AddAndCheckModuleUse(x
.moduleName
.source
,
3138 useModuleScope_
->parent().kind() == Scope::Kind::IntrinsicModules
);
3139 // use the name from this source file
3140 useModuleScope_
->symbol()->ReplaceName(x
.moduleName
.source
);
3144 void ModuleVisitor::Post(const parser::UseStmt
&x
) {
3145 if (const auto *list
{std::get_if
<std::list
<parser::Rename
>>(&x
.u
)}) {
3146 // Not a use-only: collect the names that were used in renames,
3147 // then add a use for each public name that was not renamed.
3148 std::set
<SourceName
> useNames
;
3149 for (const auto &rename
: *list
) {
3150 common::visit(common::visitors
{
3151 [&](const parser::Rename::Names
&names
) {
3152 useNames
.insert(std::get
<1>(names
.t
).source
);
3154 [&](const parser::Rename::Operators
&ops
) {
3155 useNames
.insert(std::get
<1>(ops
.t
).v
.source
);
3160 for (const auto &[name
, symbol
] : *useModuleScope_
) {
3161 if (symbol
->attrs().test(Attr::PUBLIC
) && !IsUseRenamed(symbol
->name()) &&
3162 (!symbol
->implicitAttrs().test(Attr::INTRINSIC
) ||
3163 symbol
->has
<UseDetails
>()) &&
3164 !symbol
->has
<MiscDetails
>() && useNames
.count(name
) == 0) {
3165 SourceName location
{x
.moduleName
.source
};
3166 if (auto *localSymbol
{FindInScope(name
)}) {
3167 DoAddUse(location
, localSymbol
->name(), *localSymbol
, *symbol
);
3169 DoAddUse(location
, location
, CopySymbol(name
, *symbol
), *symbol
);
3174 useModuleScope_
= nullptr;
3177 ModuleVisitor::SymbolRename
ModuleVisitor::AddUse(
3178 const SourceName
&localName
, const SourceName
&useName
) {
3179 return AddUse(localName
, useName
, FindInScope(*useModuleScope_
, useName
));
3182 ModuleVisitor::SymbolRename
ModuleVisitor::AddUse(
3183 const SourceName
&localName
, const SourceName
&useName
, Symbol
*useSymbol
) {
3184 if (!useModuleScope_
) {
3185 return {}; // error occurred finding module
3188 Say(useName
, "'%s' not found in module '%s'"_err_en_US
, MakeOpName(useName
),
3189 useModuleScope_
->GetName().value());
3192 if (useSymbol
->attrs().test(Attr::PRIVATE
) &&
3193 !FindModuleFileContaining(currScope())) {
3194 // Privacy is not enforced in module files so that generic interfaces
3195 // can be resolved to private specific procedures in specification
3197 Say(useName
, "'%s' is PRIVATE in '%s'"_err_en_US
, MakeOpName(useName
),
3198 useModuleScope_
->GetName().value());
3201 auto &localSymbol
{MakeSymbol(localName
)};
3202 DoAddUse(useName
, localName
, localSymbol
, *useSymbol
);
3203 return {&localSymbol
, useSymbol
};
3206 // symbol must be either a Use or a Generic formed by merging two uses.
3207 // Convert it to a UseError with this additional location.
3208 static bool ConvertToUseError(
3209 Symbol
&symbol
, const SourceName
&location
, const Symbol
&used
) {
3210 if (auto *ued
{symbol
.detailsIf
<UseErrorDetails
>()}) {
3211 ued
->add_occurrence(location
, used
);
3214 const auto *useDetails
{symbol
.detailsIf
<UseDetails
>()};
3216 if (auto *genericDetails
{symbol
.detailsIf
<GenericDetails
>()}) {
3217 if (!genericDetails
->uses().empty()) {
3218 useDetails
= &genericDetails
->uses().at(0)->get
<UseDetails
>();
3224 UseErrorDetails
{*useDetails
}.add_occurrence(location
, used
));
3231 // Two ultimate symbols are distinct, but they have the same name and come
3232 // from modules with the same name. At link time, their mangled names
3233 // would conflict, so they had better resolve to the same definition.
3234 // Check whether the two ultimate symbols have compatible definitions.
3235 // Returns true if no further processing is required in DoAddUse().
3236 static bool CheckCompatibleDistinctUltimates(SemanticsContext
&context
,
3237 SourceName location
, SourceName localName
, const Symbol
&localSymbol
,
3238 const Symbol
&localUltimate
, const Symbol
&useUltimate
, bool &isError
) {
3240 if (localUltimate
.has
<GenericDetails
>()) {
3241 if (useUltimate
.has
<GenericDetails
>() ||
3242 useUltimate
.has
<SubprogramDetails
>() ||
3243 useUltimate
.has
<DerivedTypeDetails
>()) {
3244 return false; // can try to merge them
3248 } else if (useUltimate
.has
<GenericDetails
>()) {
3249 if (localUltimate
.has
<SubprogramDetails
>() ||
3250 localUltimate
.has
<DerivedTypeDetails
>()) {
3251 return false; // can try to merge them
3255 } else if (localUltimate
.has
<SubprogramDetails
>()) {
3256 if (useUltimate
.has
<SubprogramDetails
>()) {
3257 auto localCharacteristics
{
3258 evaluate::characteristics::Procedure::Characterize(
3259 localUltimate
, context
.foldingContext())};
3260 auto useCharacteristics
{
3261 evaluate::characteristics::Procedure::Characterize(
3262 useUltimate
, context
.foldingContext())};
3263 if ((localCharacteristics
&&
3264 (!useCharacteristics
||
3265 *localCharacteristics
!= *useCharacteristics
)) ||
3266 (!localCharacteristics
&& useCharacteristics
)) {
3272 } else if (useUltimate
.has
<SubprogramDetails
>()) {
3274 } else if (const auto *localObject
{
3275 localUltimate
.detailsIf
<ObjectEntityDetails
>()}) {
3276 if (const auto *useObject
{useUltimate
.detailsIf
<ObjectEntityDetails
>()}) {
3277 auto localType
{evaluate::DynamicType::From(localUltimate
)};
3278 auto useType
{evaluate::DynamicType::From(useUltimate
)};
3279 if (localUltimate
.size() != useUltimate
.size() ||
3281 (!useType
|| !localType
->IsTkLenCompatibleWith(*useType
) ||
3282 !useType
->IsTkLenCompatibleWith(*localType
))) ||
3283 (!localType
&& useType
)) {
3285 } else if (IsNamedConstant(localUltimate
)) {
3286 isError
= !IsNamedConstant(useUltimate
) ||
3287 !(*localObject
->init() == *useObject
->init());
3289 isError
= IsNamedConstant(useUltimate
);
3294 } else if (useUltimate
.has
<ObjectEntityDetails
>()) {
3296 } else if (IsProcedurePointer(localUltimate
)) {
3297 isError
= !IsProcedurePointer(useUltimate
);
3298 } else if (IsProcedurePointer(useUltimate
)) {
3300 } else if (localUltimate
.has
<DerivedTypeDetails
>()) {
3301 isError
= !(useUltimate
.has
<DerivedTypeDetails
>() &&
3302 evaluate::AreSameDerivedTypeIgnoringSequence(
3303 DerivedTypeSpec
{localUltimate
.name(), localUltimate
},
3304 DerivedTypeSpec
{useUltimate
.name(), useUltimate
}));
3305 } else if (useUltimate
.has
<DerivedTypeDetails
>()) {
3307 } else if (localUltimate
.has
<NamelistDetails
>() &&
3308 useUltimate
.has
<NamelistDetails
>()) {
3309 } else if (localUltimate
.has
<CommonBlockDetails
>() &&
3310 useUltimate
.has
<CommonBlockDetails
>()) {
3314 return true; // don't try to merge generics (or whatever)
3317 void ModuleVisitor::DoAddUse(SourceName location
, SourceName localName
,
3318 Symbol
&originalLocal
, const Symbol
&useSymbol
) {
3319 Symbol
*localSymbol
{&originalLocal
};
3320 if (auto *details
{localSymbol
->detailsIf
<UseErrorDetails
>()}) {
3321 details
->add_occurrence(location
, useSymbol
);
3324 const Symbol
&useUltimate
{useSymbol
.GetUltimate()};
3325 const auto *useGeneric
{useUltimate
.detailsIf
<GenericDetails
>()};
3326 if (localSymbol
->has
<UnknownDetails
>()) {
3328 ((useGeneric
->specific() &&
3329 IsProcedurePointer(*useGeneric
->specific())) ||
3330 (useGeneric
->derivedType() &&
3331 useUltimate
.name() != localSymbol
->name()))) {
3332 // We are use-associating a generic that either shadows a procedure
3333 // pointer or shadows a derived type with a distinct name.
3334 // Local references that might be made to the procedure pointer should
3335 // use a UseDetails symbol for proper data addressing, and a derived
3336 // type needs to be in scope with its local name. So create an
3337 // empty local generic now into which the use-associated generic may
3339 localSymbol
->set_details(GenericDetails
{});
3340 localSymbol
->get
<GenericDetails
>().set_kind(useGeneric
->kind());
3341 } else { // just create UseDetails
3342 localSymbol
->set_details(UseDetails
{localName
, useSymbol
});
3343 localSymbol
->attrs() =
3344 useSymbol
.attrs() & ~Attrs
{Attr::PUBLIC
, Attr::PRIVATE
, Attr::SAVE
};
3345 localSymbol
->implicitAttrs() =
3346 localSymbol
->attrs() & Attrs
{Attr::ASYNCHRONOUS
, Attr::VOLATILE
};
3347 localSymbol
->flags() = useSymbol
.flags();
3352 Symbol
&localUltimate
{localSymbol
->GetUltimate()};
3353 if (&localUltimate
== &useUltimate
) {
3354 // use-associating the same symbol again -- ok
3357 if (useUltimate
.owner().IsModule() && localUltimate
.owner().IsSubmodule() &&
3358 DoesScopeContain(&useUltimate
.owner(), localUltimate
)) {
3359 // Within a submodule, USE'ing a symbol that comes indirectly
3360 // from the ancestor module, e.g. foo in:
3361 // MODULE m1; INTERFACE; MODULE SUBROUTINE foo; END INTERFACE; END
3362 // MODULE m2; USE m1; END
3363 // SUBMODULE m1(sm); USE m2; CONTAINS; MODULE PROCEDURE foo; END; END
3364 return; // ok, ignore it
3367 if (localUltimate
.name() == useUltimate
.name() &&
3368 localUltimate
.owner().IsModule() && useUltimate
.owner().IsModule() &&
3369 localUltimate
.owner().GetName() &&
3370 localUltimate
.owner().GetName() == useUltimate
.owner().GetName()) {
3371 bool isError
{false};
3372 if (CheckCompatibleDistinctUltimates(context(), location
, localName
,
3373 *localSymbol
, localUltimate
, useUltimate
, isError
)) {
3375 // Convert the local symbol to a UseErrorDetails, if possible;
3376 // otherwise emit a fatal error.
3377 if (!ConvertToUseError(*localSymbol
, location
, useSymbol
)) {
3380 "'%s' use-associated from '%s' in module '%s' is incompatible with '%s' from another module"_err_en_US
,
3381 localName
, useUltimate
.name(),
3382 useUltimate
.owner().GetName().value(), localUltimate
.name())
3383 .Attach(useUltimate
.name(), "First declaration"_en_US
)
3384 .Attach(localUltimate
.name(), "Other declaration"_en_US
);
3388 if (auto *msg
{context().Warn(
3389 common::UsageWarning::CompatibleDeclarationsFromDistinctModules
,
3391 "'%s' is use-associated from '%s' in two distinct instances of module '%s'"_warn_en_US
,
3392 localName
, localUltimate
.name(),
3393 localUltimate
.owner().GetName().value())}) {
3394 msg
->Attach(localUltimate
.name(), "Previous declaration"_en_US
)
3395 .Attach(useUltimate
.name(), "Later declaration"_en_US
);
3401 // There are many possible combinations of symbol types that could arrive
3402 // with the same (local) name vie USE association from distinct modules.
3403 // Fortran allows a generic interface to share its name with a derived type,
3404 // or with the name of a non-generic procedure (which should be one of the
3405 // generic's specific procedures). Implementing all these possibilities is
3407 // Error cases are converted into UseErrorDetails symbols to trigger error
3408 // messages when/if bad combinations are actually used later in the program.
3409 // The error cases are:
3410 // - two distinct derived types
3411 // - two distinct non-generic procedures
3412 // - a generic and a non-generic that is not already one of its specifics
3413 // - anything other than a derived type, non-generic procedure, or
3414 // generic procedure being combined with something other than an
3415 // prior USE association of itself
3416 auto *localGeneric
{localUltimate
.detailsIf
<GenericDetails
>()};
3417 Symbol
*localDerivedType
{nullptr};
3418 if (localUltimate
.has
<DerivedTypeDetails
>()) {
3419 localDerivedType
= &localUltimate
;
3420 } else if (localGeneric
) {
3421 if (auto *dt
{localGeneric
->derivedType()};
3422 dt
&& !dt
->attrs().test(Attr::PRIVATE
)) {
3423 localDerivedType
= dt
;
3426 const Symbol
*useDerivedType
{nullptr};
3427 if (useUltimate
.has
<DerivedTypeDetails
>()) {
3428 useDerivedType
= &useUltimate
;
3429 } else if (useGeneric
) {
3430 if (const auto *dt
{useGeneric
->derivedType()};
3431 dt
&& !dt
->attrs().test(Attr::PRIVATE
)) {
3432 useDerivedType
= dt
;
3436 Symbol
*localProcedure
{nullptr};
3438 if (localGeneric
->specific() &&
3439 !localGeneric
->specific()->attrs().test(Attr::PRIVATE
)) {
3440 localProcedure
= localGeneric
->specific();
3442 } else if (IsProcedure(localUltimate
)) {
3443 localProcedure
= &localUltimate
;
3445 const Symbol
*useProcedure
{nullptr};
3447 if (useGeneric
->specific() &&
3448 !useGeneric
->specific()->attrs().test(Attr::PRIVATE
)) {
3449 useProcedure
= useGeneric
->specific();
3451 } else if (IsProcedure(useUltimate
)) {
3452 useProcedure
= &useUltimate
;
3455 // Creates a UseErrorDetails symbol in the current scope for a
3456 // current UseDetails symbol, but leaves the UseDetails in the
3457 // scope's name map.
3458 auto CreateLocalUseError
{[&]() {
3459 EraseSymbol(*localSymbol
);
3460 CHECK(localSymbol
->has
<UseDetails
>());
3461 UseErrorDetails details
{localSymbol
->get
<UseDetails
>()};
3462 details
.add_occurrence(location
, useSymbol
);
3463 Symbol
*newSymbol
{&MakeSymbol(localName
, Attrs
{}, std::move(details
))};
3464 // Restore *localSymbol in currScope
3465 auto iter
{currScope().find(localName
)};
3466 CHECK(iter
!= currScope().end() && &*iter
->second
== newSymbol
);
3467 iter
->second
= MutableSymbolRef
{*localSymbol
};
3471 // When two derived types arrived, try to combine them.
3472 const Symbol
*combinedDerivedType
{nullptr};
3473 if (!useDerivedType
) {
3474 combinedDerivedType
= localDerivedType
;
3475 } else if (!localDerivedType
) {
3476 if (useDerivedType
->name() == localName
) {
3477 combinedDerivedType
= useDerivedType
;
3479 combinedDerivedType
=
3480 &currScope().MakeSymbol(localSymbol
->name(), useDerivedType
->attrs(),
3481 UseDetails
{localSymbol
->name(), *useDerivedType
});
3483 } else if (&localDerivedType
->GetUltimate() ==
3484 &useDerivedType
->GetUltimate()) {
3485 combinedDerivedType
= localDerivedType
;
3487 const Scope
*localScope
{localDerivedType
->GetUltimate().scope()};
3488 const Scope
*useScope
{useDerivedType
->GetUltimate().scope()};
3489 if (localScope
&& useScope
&& localScope
->derivedTypeSpec() &&
3490 useScope
->derivedTypeSpec() &&
3491 evaluate::AreSameDerivedType(
3492 *localScope
->derivedTypeSpec(), *useScope
->derivedTypeSpec())) {
3493 combinedDerivedType
= localDerivedType
;
3495 // Create a local UseErrorDetails for the ambiguous derived type
3497 combinedDerivedType
= CreateLocalUseError();
3499 ConvertToUseError(*localSymbol
, location
, useSymbol
);
3500 localDerivedType
= nullptr;
3501 localGeneric
= nullptr;
3502 combinedDerivedType
= localSymbol
;
3505 if (!localGeneric
&& !useGeneric
) {
3506 return; // both symbols are derived types; done
3510 auto AreSameProcedure
{[&](const Symbol
&p1
, const Symbol
&p2
) {
3513 } else if (p1
.name() != p2
.name()) {
3515 } else if (p1
.attrs().test(Attr::INTRINSIC
) ||
3516 p2
.attrs().test(Attr::INTRINSIC
)) {
3517 return p1
.attrs().test(Attr::INTRINSIC
) &&
3518 p2
.attrs().test(Attr::INTRINSIC
);
3519 } else if (!IsProcedure(p1
) || !IsProcedure(p2
)) {
3521 } else if (IsPointer(p1
) || IsPointer(p2
)) {
3523 } else if (const auto *subp
{p1
.detailsIf
<SubprogramDetails
>()};
3524 subp
&& !subp
->isInterface()) {
3525 return false; // defined in module, not an external
3526 } else if (const auto *subp
{p2
.detailsIf
<SubprogramDetails
>()};
3527 subp
&& !subp
->isInterface()) {
3528 return false; // defined in module, not an external
3530 // Both are external interfaces, perhaps to the same procedure
3531 auto class1
{ClassifyProcedure(p1
)};
3532 auto class2
{ClassifyProcedure(p2
)};
3533 if (class1
== ProcedureDefinitionClass::External
&&
3534 class2
== ProcedureDefinitionClass::External
) {
3535 auto chars1
{evaluate::characteristics::Procedure::Characterize(
3536 p1
, GetFoldingContext())};
3537 auto chars2
{evaluate::characteristics::Procedure::Characterize(
3538 p2
, GetFoldingContext())};
3539 // same procedure interface defined identically in two modules?
3540 return chars1
&& chars2
&& *chars1
== *chars2
;
3547 // When two non-generic procedures arrived, try to combine them.
3548 const Symbol
*combinedProcedure
{nullptr};
3549 if (!localProcedure
) {
3550 combinedProcedure
= useProcedure
;
3551 } else if (!useProcedure
) {
3552 combinedProcedure
= localProcedure
;
3554 if (AreSameProcedure(
3555 localProcedure
->GetUltimate(), useProcedure
->GetUltimate())) {
3556 if (!localGeneric
&& !useGeneric
) {
3557 return; // both symbols are non-generic procedures
3559 combinedProcedure
= localProcedure
;
3563 // Prepare to merge generics
3564 bool cantCombine
{false};
3566 if (useGeneric
|| useDerivedType
) {
3567 } else if (&useUltimate
== &BypassGeneric(localUltimate
).GetUltimate()) {
3568 return; // nothing to do; used subprogram is local's specific
3569 } else if (useUltimate
.attrs().test(Attr::INTRINSIC
) &&
3570 useUltimate
.name() == localSymbol
->name()) {
3571 return; // local generic can extend intrinsic
3573 for (const auto &ref
: localGeneric
->specificProcs()) {
3574 if (&ref
->GetUltimate() == &useUltimate
) {
3575 return; // used non-generic is already a specific of local generic
3580 } else if (useGeneric
) {
3581 if (localDerivedType
) {
3582 } else if (&localUltimate
== &BypassGeneric(useUltimate
).GetUltimate() ||
3583 (localSymbol
->attrs().test(Attr::INTRINSIC
) &&
3584 localUltimate
.name() == useUltimate
.name())) {
3585 // Local is the specific of the used generic or an intrinsic with the
3586 // same name; replace it.
3587 EraseSymbol(*localSymbol
);
3588 Symbol
&newSymbol
{MakeSymbol(localName
,
3589 useUltimate
.attrs() & ~Attrs
{Attr::PUBLIC
, Attr::PRIVATE
},
3590 UseDetails
{localName
, useUltimate
})};
3591 newSymbol
.flags() = useSymbol
.flags();
3594 for (const auto &ref
: useGeneric
->specificProcs()) {
3595 if (&ref
->GetUltimate() == &localUltimate
) {
3596 return; // local non-generic is already a specific of used generic
3605 // If symbols are not combinable, create a use error.
3607 if (!ConvertToUseError(*localSymbol
, location
, useSymbol
)) {
3609 "Cannot use-associate '%s'; it is already declared in this scope"_err_en_US
,
3611 .Attach(localSymbol
->name(), "Previous declaration of '%s'"_en_US
,
3617 // At this point, there must be at least one generic interface.
3618 CHECK(localGeneric
|| (useGeneric
&& (localDerivedType
|| localProcedure
)));
3620 // Ensure that a use-associated specific procedure that is a procedure
3621 // pointer is properly represented as a USE association of an entity.
3622 if (IsProcedurePointer(useProcedure
)) {
3623 Symbol
&combined
{currScope().MakeSymbol(localSymbol
->name(),
3624 useProcedure
->attrs(), UseDetails
{localName
, *useProcedure
})};
3625 combined
.flags() |= useProcedure
->flags();
3626 combinedProcedure
= &combined
;
3630 // Create a local copy of a previously use-associated generic so that
3631 // it can be locally extended without corrupting the original.
3632 if (localSymbol
->has
<UseDetails
>()) {
3633 GenericDetails generic
;
3634 generic
.CopyFrom(DEREF(localGeneric
));
3635 EraseSymbol(*localSymbol
);
3636 Symbol
&newSymbol
{MakeSymbol(
3637 localSymbol
->name(), localSymbol
->attrs(), std::move(generic
))};
3638 newSymbol
.flags() = localSymbol
->flags();
3639 localGeneric
= &newSymbol
.get
<GenericDetails
>();
3640 localGeneric
->AddUse(*localSymbol
);
3641 localSymbol
= &newSymbol
;
3644 // Combine two use-associated generics
3645 localSymbol
->attrs() =
3646 useSymbol
.attrs() & ~Attrs
{Attr::PUBLIC
, Attr::PRIVATE
};
3647 localSymbol
->flags() = useSymbol
.flags();
3648 AddGenericUse(*localGeneric
, localName
, useUltimate
);
3649 localGeneric
->clear_derivedType();
3650 localGeneric
->CopyFrom(*useGeneric
);
3652 localGeneric
->clear_derivedType();
3653 if (combinedDerivedType
) {
3654 localGeneric
->set_derivedType(*const_cast<Symbol
*>(combinedDerivedType
));
3656 localGeneric
->clear_specific();
3657 if (combinedProcedure
) {
3658 localGeneric
->set_specific(*const_cast<Symbol
*>(combinedProcedure
));
3661 CHECK(localSymbol
->has
<UseDetails
>());
3662 // Create a local copy of the use-associated generic, then extend it
3663 // with the combined derived type &/or non-generic procedure.
3664 GenericDetails generic
;
3665 generic
.CopyFrom(*useGeneric
);
3666 EraseSymbol(*localSymbol
);
3667 Symbol
&newSymbol
{MakeSymbol(localName
,
3668 useUltimate
.attrs() & ~Attrs
{Attr::PUBLIC
, Attr::PRIVATE
},
3669 std::move(generic
))};
3670 newSymbol
.flags() = useUltimate
.flags();
3671 auto &newUseGeneric
{newSymbol
.get
<GenericDetails
>()};
3672 AddGenericUse(newUseGeneric
, localName
, useUltimate
);
3673 newUseGeneric
.AddUse(*localSymbol
);
3674 if (combinedDerivedType
) {
3675 if (const auto *oldDT
{newUseGeneric
.derivedType()}) {
3676 CHECK(&oldDT
->GetUltimate() == &combinedDerivedType
->GetUltimate());
3678 newUseGeneric
.set_derivedType(
3679 *const_cast<Symbol
*>(combinedDerivedType
));
3682 if (combinedProcedure
) {
3683 newUseGeneric
.set_specific(*const_cast<Symbol
*>(combinedProcedure
));
3688 void ModuleVisitor::AddUse(const GenericSpecInfo
&info
) {
3689 if (useModuleScope_
) {
3690 const auto &name
{info
.symbolName()};
3691 auto rename
{AddUse(name
, name
, FindInScope(*useModuleScope_
, name
))};
3692 info
.Resolve(rename
.use
);
3696 // Create a UseDetails symbol for this USE and add it to generic
3697 Symbol
&ModuleVisitor::AddGenericUse(
3698 GenericDetails
&generic
, const SourceName
&name
, const Symbol
&useSymbol
) {
3700 currScope().MakeSymbol(name
, {}, UseDetails
{name
, useSymbol
})};
3701 generic
.AddUse(newSymbol
);
3705 // Enforce F'2023 C1406 as a warning
3706 void ModuleVisitor::AddAndCheckModuleUse(SourceName name
, bool isIntrinsic
) {
3708 if (auto iter
{nonIntrinsicUses_
.find(name
)};
3709 iter
!= nonIntrinsicUses_
.end()) {
3710 if (auto *msg
{context().Warn(common::LanguageFeature::MiscUseExtensions
,
3712 "Should not USE the intrinsic module '%s' in the same scope as a USE of the non-intrinsic module"_port_en_US
,
3714 msg
->Attach(*iter
, "Previous USE of '%s'"_en_US
, *iter
);
3717 intrinsicUses_
.insert(name
);
3719 if (auto iter
{intrinsicUses_
.find(name
)}; iter
!= intrinsicUses_
.end()) {
3720 if (auto *msg
{context().Warn(common::LanguageFeature::MiscUseExtensions
,
3722 "Should not USE the non-intrinsic module '%s' in the same scope as a USE of the intrinsic module"_port_en_US
,
3724 msg
->Attach(*iter
, "Previous USE of '%s'"_en_US
, *iter
);
3727 nonIntrinsicUses_
.insert(name
);
3731 bool ModuleVisitor::BeginSubmodule(
3732 const parser::Name
&name
, const parser::ParentIdentifier
&parentId
) {
3733 const auto &ancestorName
{std::get
<parser::Name
>(parentId
.t
)};
3734 Scope
*parentScope
{nullptr};
3735 Scope
*ancestor
{FindModule(ancestorName
, false /*not intrinsic*/)};
3737 if (const auto &parentName
{
3738 std::get
<std::optional
<parser::Name
>>(parentId
.t
)}) {
3739 parentScope
= FindModule(*parentName
, false /*not intrinsic*/, ancestor
);
3741 parentScope
= ancestor
;
3745 PushScope(*parentScope
);
3747 // Error recovery: there's no ancestor scope, so create a dummy one to
3748 // hold the submodule's scope.
3749 SourceName dummyName
{context().GetTempName(currScope())};
3750 Symbol
&dummySymbol
{MakeSymbol(dummyName
, Attrs
{}, ModuleDetails
{false})};
3751 PushScope(Scope::Kind::Module
, &dummySymbol
);
3752 parentScope
= &currScope();
3754 BeginModule(name
, true);
3755 set_inheritFromParent(false); // submodules don't inherit parents' implicits
3756 if (ancestor
&& !ancestor
->AddSubmodule(name
.source
, currScope())) {
3757 Say(name
, "Module '%s' already has a submodule named '%s'"_err_en_US
,
3758 ancestorName
.source
, name
.source
);
3763 void ModuleVisitor::BeginModule(const parser::Name
&name
, bool isSubmodule
) {
3764 // Submodule symbols are not visible in their parents' scopes.
3765 Symbol
&symbol
{isSubmodule
? Resolve(name
,
3766 currScope().MakeSymbol(name
.source
, Attrs
{},
3767 ModuleDetails
{true}))
3768 : MakeSymbol(name
, ModuleDetails
{false})};
3769 auto &details
{symbol
.get
<ModuleDetails
>()};
3770 PushScope(Scope::Kind::Module
, &symbol
);
3771 details
.set_scope(&currScope());
3772 prevAccessStmt_
= std::nullopt
;
3775 // Find a module or submodule by name and return its scope.
3776 // If ancestor is present, look for a submodule of that ancestor module.
3777 // May have to read a .mod file to find it.
3778 // If an error occurs, report it and return nullptr.
3779 Scope
*ModuleVisitor::FindModule(const parser::Name
&name
,
3780 std::optional
<bool> isIntrinsic
, Scope
*ancestor
) {
3781 ModFileReader reader
{context()};
3783 reader
.Read(name
.source
, isIntrinsic
, ancestor
, /*silent=*/false)};
3785 if (DoesScopeContain(scope
, currScope())) { // 14.2.2(1)
3786 std::optional
<SourceName
> submoduleName
;
3787 if (const Scope
* container
{FindModuleOrSubmoduleContaining(currScope())};
3788 container
&& container
->IsSubmodule()) {
3789 submoduleName
= container
->GetName();
3791 if (submoduleName
) {
3793 "Module '%s' cannot USE itself from its own submodule '%s'"_err_en_US
,
3794 name
.source
, *submoduleName
);
3796 Say(name
, "Module '%s' cannot USE itself"_err_en_US
);
3799 Resolve(name
, scope
->symbol());
3804 void ModuleVisitor::ApplyDefaultAccess() {
3805 const auto *moduleDetails
{
3806 DEREF(currScope().symbol()).detailsIf
<ModuleDetails
>()};
3807 CHECK(moduleDetails
);
3809 DEREF(moduleDetails
).isDefaultPrivate() ? Attr::PRIVATE
: Attr::PUBLIC
};
3810 for (auto &pair
: currScope()) {
3811 Symbol
&symbol
{*pair
.second
};
3812 if (!symbol
.attrs().HasAny({Attr::PUBLIC
, Attr::PRIVATE
})) {
3813 Attr attr
{defaultAttr
};
3814 if (auto *generic
{symbol
.detailsIf
<GenericDetails
>()}) {
3815 if (generic
->derivedType()) {
3816 // If a generic interface has a derived type of the same
3817 // name that has an explicit accessibility attribute, then
3818 // the generic must have the same accessibility.
3819 if (generic
->derivedType()->attrs().test(Attr::PUBLIC
)) {
3820 attr
= Attr::PUBLIC
;
3821 } else if (generic
->derivedType()->attrs().test(Attr::PRIVATE
)) {
3822 attr
= Attr::PRIVATE
;
3826 SetImplicitAttr(symbol
, attr
);
3831 // InterfaceVistor implementation
3833 bool InterfaceVisitor::Pre(const parser::InterfaceStmt
&x
) {
3834 bool isAbstract
{std::holds_alternative
<parser::Abstract
>(x
.u
)};
3835 genericInfo_
.emplace(/*isInterface*/ true, isAbstract
);
3836 return BeginAttrs();
3839 void InterfaceVisitor::Post(const parser::InterfaceStmt
&) { EndAttrs(); }
3841 void InterfaceVisitor::Post(const parser::EndInterfaceStmt
&) {
3842 ResolveNewSpecifics();
3846 // Create a symbol in genericSymbol_ for this GenericSpec.
3847 bool InterfaceVisitor::Pre(const parser::GenericSpec
&x
) {
3848 if (auto *symbol
{FindInScope(GenericSpecInfo
{x
}.symbolName())}) {
3849 SetGenericSymbol(*symbol
);
3854 bool InterfaceVisitor::Pre(const parser::ProcedureStmt
&x
) {
3856 Say("A PROCEDURE statement is only allowed in a generic interface block"_err_en_US
);
3858 auto kind
{std::get
<parser::ProcedureStmt::Kind
>(x
.t
)};
3859 const auto &names
{std::get
<std::list
<parser::Name
>>(x
.t
)};
3860 AddSpecificProcs(names
, kind
);
3865 bool InterfaceVisitor::Pre(const parser::GenericStmt
&) {
3866 genericInfo_
.emplace(/*isInterface*/ false);
3867 return BeginAttrs();
3869 void InterfaceVisitor::Post(const parser::GenericStmt
&x
) {
3870 auto attrs
{EndAttrs()};
3871 if (Symbol
* symbol
{GetGenericInfo().symbol
}) {
3872 SetExplicitAttrs(*symbol
, attrs
);
3874 const auto &names
{std::get
<std::list
<parser::Name
>>(x
.t
)};
3875 AddSpecificProcs(names
, ProcedureKind::Procedure
);
3876 ResolveNewSpecifics();
3880 bool InterfaceVisitor::inInterfaceBlock() const {
3881 return !genericInfo_
.empty() && GetGenericInfo().isInterface
;
3883 bool InterfaceVisitor::isGeneric() const {
3884 return !genericInfo_
.empty() && GetGenericInfo().symbol
;
3886 bool InterfaceVisitor::isAbstract() const {
3887 return !genericInfo_
.empty() && GetGenericInfo().isAbstract
;
3890 void InterfaceVisitor::AddSpecificProcs(
3891 const std::list
<parser::Name
> &names
, ProcedureKind kind
) {
3892 if (Symbol
* symbol
{GetGenericInfo().symbol
};
3893 symbol
&& symbol
->has
<GenericDetails
>()) {
3894 for (const auto &name
: names
) {
3895 specificsForGenericProcs_
.emplace(symbol
, std::make_pair(&name
, kind
));
3896 genericsForSpecificProcs_
.emplace(name
.source
, symbol
);
3901 // By now we should have seen all specific procedures referenced by name in
3902 // this generic interface. Resolve those names to symbols.
3903 void GenericHandler::ResolveSpecificsInGeneric(
3904 Symbol
&generic
, bool isEndOfSpecificationPart
) {
3905 auto &details
{generic
.get
<GenericDetails
>()};
3906 UnorderedSymbolSet symbolsSeen
;
3907 for (const Symbol
&symbol
: details
.specificProcs()) {
3908 symbolsSeen
.insert(symbol
.GetUltimate());
3910 auto range
{specificsForGenericProcs_
.equal_range(&generic
)};
3911 SpecificProcMapType retain
;
3912 for (auto it
{range
.first
}; it
!= range
.second
; ++it
) {
3913 const parser::Name
*name
{it
->second
.first
};
3914 auto kind
{it
->second
.second
};
3915 const Symbol
*symbol
{isEndOfSpecificationPart
3917 : FindInScope(generic
.owner(), *name
)};
3918 ProcedureDefinitionClass defClass
{ProcedureDefinitionClass::None
};
3919 const Symbol
*specific
{symbol
};
3920 const Symbol
*ultimate
{nullptr};
3922 // Subtlety: when *symbol is a use- or host-association, the specific
3923 // procedure that is recorded in the GenericDetails below must be *symbol,
3924 // not the specific procedure shadowed by a generic, because that specific
3925 // procedure may be a symbol from another module and its name unavailable
3926 // to emit to a module file.
3927 const Symbol
&bypassed
{BypassGeneric(*symbol
)};
3928 if (symbol
== &symbol
->GetUltimate()) {
3929 specific
= &bypassed
;
3931 ultimate
= &bypassed
.GetUltimate();
3932 defClass
= ClassifyProcedure(*ultimate
);
3934 std::optional
<MessageFixedText
> error
;
3935 if (defClass
== ProcedureDefinitionClass::Module
) {
3937 } else if (kind
== ProcedureKind::ModuleProcedure
) {
3938 error
= "'%s' is not a module procedure"_err_en_US
;
3941 case ProcedureDefinitionClass::Intrinsic
:
3942 case ProcedureDefinitionClass::External
:
3943 case ProcedureDefinitionClass::Internal
:
3944 case ProcedureDefinitionClass::Dummy
:
3945 case ProcedureDefinitionClass::Pointer
:
3947 case ProcedureDefinitionClass::None
:
3948 error
= "'%s' is not a procedure"_err_en_US
;
3952 "'%s' is not a procedure that can appear in a generic interface"_err_en_US
;
3957 if (isEndOfSpecificationPart
) {
3958 Say(*name
, std::move(*error
));
3960 // possible forward reference, catch it later
3961 retain
.emplace(&generic
, std::make_pair(name
, kind
));
3963 } else if (!ultimate
) {
3964 } else if (symbolsSeen
.insert(*ultimate
).second
/*true if added*/) {
3965 // When a specific procedure is a USE association, that association
3966 // is saved in the generic's specifics, not its ultimate symbol,
3967 // so that module file output of interfaces can distinguish them.
3968 details
.AddSpecificProc(*specific
, name
->source
);
3969 } else if (specific
== ultimate
) {
3971 "Procedure '%s' is already specified in generic '%s'"_err_en_US
,
3972 name
->source
, MakeOpName(generic
.name()));
3975 "Procedure '%s' from module '%s' is already specified in generic '%s'"_err_en_US
,
3976 ultimate
->name(), ultimate
->owner().GetName().value(),
3977 MakeOpName(generic
.name()));
3980 specificsForGenericProcs_
.erase(range
.first
, range
.second
);
3981 specificsForGenericProcs_
.merge(std::move(retain
));
3984 void GenericHandler::DeclaredPossibleSpecificProc(Symbol
&proc
) {
3985 auto range
{genericsForSpecificProcs_
.equal_range(proc
.name())};
3986 for (auto iter
{range
.first
}; iter
!= range
.second
; ++iter
) {
3987 ResolveSpecificsInGeneric(*iter
->second
, false);
3991 void InterfaceVisitor::ResolveNewSpecifics() {
3992 if (Symbol
* generic
{genericInfo_
.top().symbol
};
3993 generic
&& generic
->has
<GenericDetails
>()) {
3994 ResolveSpecificsInGeneric(*generic
, false);
3998 // Mixed interfaces are allowed by the standard.
3999 // If there is a derived type with the same name, they must all be functions.
4000 void InterfaceVisitor::CheckGenericProcedures(Symbol
&generic
) {
4001 ResolveSpecificsInGeneric(generic
, true);
4002 auto &details
{generic
.get
<GenericDetails
>()};
4003 if (auto *proc
{details
.CheckSpecific()}) {
4004 context().Warn(common::UsageWarning::HomonymousSpecific
,
4005 proc
->name().begin() > generic
.name().begin() ? proc
->name()
4007 "'%s' should not be the name of both a generic interface and a procedure unless it is a specific procedure of the generic"_warn_en_US
,
4010 auto &specifics
{details
.specificProcs()};
4011 if (specifics
.empty()) {
4012 if (details
.derivedType()) {
4013 generic
.set(Symbol::Flag::Function
);
4017 const Symbol
*function
{nullptr};
4018 const Symbol
*subroutine
{nullptr};
4019 for (const Symbol
&specific
: specifics
) {
4020 if (!function
&& specific
.test(Symbol::Flag::Function
)) {
4021 function
= &specific
;
4022 } else if (!subroutine
&& specific
.test(Symbol::Flag::Subroutine
)) {
4023 subroutine
= &specific
;
4024 if (details
.derivedType() &&
4025 context().ShouldWarn(
4026 common::LanguageFeature::SubroutineAndFunctionSpecifics
) &&
4028 SayDerivedType(generic
.name(),
4029 "Generic interface '%s' should only contain functions due to derived type with same name"_warn_en_US
,
4030 *details
.derivedType()->GetUltimate().scope())
4031 .set_languageFeature(
4032 common::LanguageFeature::SubroutineAndFunctionSpecifics
);
4035 if (function
&& subroutine
) { // F'2023 C1514
4036 if (auto *msg
{context().Warn(
4037 common::LanguageFeature::SubroutineAndFunctionSpecifics
,
4039 "Generic interface '%s' has both a function and a subroutine"_warn_en_US
,
4041 msg
->Attach(function
->name(), "Function declaration"_en_US
)
4042 .Attach(subroutine
->name(), "Subroutine declaration"_en_US
);
4047 if (function
&& !subroutine
) {
4048 generic
.set(Symbol::Flag::Function
);
4049 } else if (subroutine
&& !function
) {
4050 generic
.set(Symbol::Flag::Subroutine
);
4054 // SubprogramVisitor implementation
4056 // Return false if it is actually an assignment statement.
4057 bool SubprogramVisitor::HandleStmtFunction(const parser::StmtFunctionStmt
&x
) {
4058 const auto &name
{std::get
<parser::Name
>(x
.t
)};
4059 const DeclTypeSpec
*resultType
{nullptr};
4060 // Look up name: provides return type or tells us if it's an array
4061 if (auto *symbol
{FindSymbol(name
)}) {
4062 Symbol
&ultimate
{symbol
->GetUltimate()};
4063 if (ultimate
.has
<ObjectEntityDetails
>() ||
4064 ultimate
.has
<AssocEntityDetails
>() ||
4065 CouldBeDataPointerValuedFunction(&ultimate
) ||
4066 (&symbol
->owner() == &currScope() && IsFunctionResult(*symbol
))) {
4067 misparsedStmtFuncFound_
= true;
4070 if (IsHostAssociated(*symbol
, currScope())) {
4071 context().Warn(common::LanguageFeature::StatementFunctionExtensions
,
4073 "Name '%s' from host scope should have a type declaration before its local statement function definition"_port_en_US
,
4075 MakeSymbol(name
, Attrs
{}, UnknownDetails
{});
4076 } else if (auto *entity
{ultimate
.detailsIf
<EntityDetails
>()};
4077 entity
&& !ultimate
.has
<ProcEntityDetails
>()) {
4078 resultType
= entity
->type();
4079 ultimate
.details() = UnknownDetails
{}; // will be replaced below
4081 misparsedStmtFuncFound_
= true;
4084 if (misparsedStmtFuncFound_
) {
4086 "'%s' has not been declared as an array or pointer-valued function"_err_en_US
);
4089 auto &symbol
{PushSubprogramScope(name
, Symbol::Flag::Function
)};
4090 symbol
.set(Symbol::Flag::StmtFunction
);
4091 EraseSymbol(symbol
); // removes symbol added by PushSubprogramScope
4092 auto &details
{symbol
.get
<SubprogramDetails
>()};
4093 for (const auto &dummyName
: std::get
<std::list
<parser::Name
>>(x
.t
)) {
4094 ObjectEntityDetails dummyDetails
{true};
4095 if (auto *dummySymbol
{FindInScope(currScope().parent(), dummyName
)}) {
4096 if (auto *d
{dummySymbol
->GetType()}) {
4097 dummyDetails
.set_type(*d
);
4100 Symbol
&dummy
{MakeSymbol(dummyName
, std::move(dummyDetails
))};
4101 ApplyImplicitRules(dummy
);
4102 details
.add_dummyArg(dummy
);
4104 ObjectEntityDetails resultDetails
;
4106 resultDetails
.set_type(*resultType
);
4108 resultDetails
.set_funcResult(true);
4109 Symbol
&result
{MakeSymbol(name
, std::move(resultDetails
))};
4110 result
.flags().set(Symbol::Flag::StmtFunction
);
4111 ApplyImplicitRules(result
);
4112 details
.set_result(result
);
4113 // The analysis of the expression that constitutes the body of the
4114 // statement function is deferred to FinishSpecificationPart() so that
4115 // all declarations and implicit typing are complete.
4120 bool SubprogramVisitor::Pre(const parser::Suffix
&suffix
) {
4121 if (suffix
.resultName
) {
4122 if (IsFunction(currScope())) {
4123 if (FuncResultStack::FuncInfo
* info
{funcResultStack().Top()}) {
4124 if (info
->inFunctionStmt
) {
4125 info
->resultName
= &suffix
.resultName
.value();
4127 // will check the result name in Post(EntryStmt)
4131 Message
&msg
{Say(*suffix
.resultName
,
4132 "RESULT(%s) may appear only in a function"_err_en_US
)};
4133 if (const Symbol
* subprogram
{InclusiveScope().symbol()}) {
4134 msg
.Attach(subprogram
->name(), "Containing subprogram"_en_US
);
4138 // LanguageBindingSpec deferred to Post(EntryStmt) or, for FunctionStmt,
4139 // all the way to EndSubprogram().
4143 bool SubprogramVisitor::Pre(const parser::PrefixSpec
&x
) {
4144 // Save this to process after UseStmt and ImplicitPart
4145 if (const auto *parsedType
{std::get_if
<parser::DeclarationTypeSpec
>(&x
.u
)}) {
4146 if (FuncResultStack::FuncInfo
* info
{funcResultStack().Top()}) {
4147 if (info
->parsedType
) { // C1543
4148 Say(currStmtSource().value_or(info
->source
),
4149 "FUNCTION prefix cannot specify the type more than once"_err_en_US
);
4151 info
->parsedType
= parsedType
;
4152 if (auto at
{currStmtSource()}) {
4157 Say(currStmtSource().value(),
4158 "SUBROUTINE prefix cannot specify a type"_err_en_US
);
4166 bool SubprogramVisitor::Pre(const parser::PrefixSpec::Attributes
&attrs
) {
4167 if (auto *subp
{currScope().symbol()
4168 ? currScope().symbol()->detailsIf
<SubprogramDetails
>()
4170 for (auto attr
: attrs
.v
) {
4171 if (auto current
{subp
->cudaSubprogramAttrs()}) {
4172 if (attr
== *current
||
4173 (*current
== common::CUDASubprogramAttrs::HostDevice
&&
4174 (attr
== common::CUDASubprogramAttrs::Host
||
4175 attr
== common::CUDASubprogramAttrs::Device
))) {
4176 context().Warn(common::LanguageFeature::RedundantAttribute
,
4177 currStmtSource().value(),
4178 "ATTRIBUTES(%s) appears more than once"_warn_en_US
,
4179 common::EnumToString(attr
));
4180 } else if ((attr
== common::CUDASubprogramAttrs::Host
||
4181 attr
== common::CUDASubprogramAttrs::Device
) &&
4182 (*current
== common::CUDASubprogramAttrs::Host
||
4183 *current
== common::CUDASubprogramAttrs::Device
||
4184 *current
== common::CUDASubprogramAttrs::HostDevice
)) {
4185 // HOST,DEVICE or DEVICE,HOST -> HostDevice
4186 subp
->set_cudaSubprogramAttrs(
4187 common::CUDASubprogramAttrs::HostDevice
);
4189 Say(currStmtSource().value(),
4190 "ATTRIBUTES(%s) conflicts with earlier ATTRIBUTES(%s)"_err_en_US
,
4191 common::EnumToString(attr
), common::EnumToString(*current
));
4194 subp
->set_cudaSubprogramAttrs(attr
);
4197 if (auto attrs
{subp
->cudaSubprogramAttrs()}) {
4198 if (*attrs
== common::CUDASubprogramAttrs::Global
||
4199 *attrs
== common::CUDASubprogramAttrs::Device
) {
4200 const Scope
&scope
{currScope()};
4201 const Scope
*mod
{FindModuleContaining(scope
)};
4203 (mod
->GetName().value() == "cudadevice" ||
4204 mod
->GetName().value() == "__cuda_device")) {
4207 // Implicitly USE the cudadevice module by copying its symbols in the
4209 const Scope
&cudaDeviceScope
{context().GetCUDADeviceScope()};
4210 for (auto sym
: cudaDeviceScope
.GetSymbols()) {
4211 if (!currScope().FindSymbol(sym
->name())) {
4212 auto &localSymbol
{MakeSymbol(
4213 sym
->name(), Attrs
{}, UseDetails
{sym
->name(), *sym
})};
4214 localSymbol
.flags() = sym
->flags();
4223 void SubprogramVisitor::Post(const parser::PrefixSpec::Launch_Bounds
&x
) {
4224 std::vector
<std::int64_t> bounds
;
4226 for (const auto &sicx
: x
.v
) {
4227 if (auto value
{evaluate::ToInt64(EvaluateExpr(sicx
))}) {
4228 bounds
.push_back(*value
);
4233 if (!ok
|| bounds
.size() < 2 || bounds
.size() > 3) {
4234 Say(currStmtSource().value(),
4235 "Operands of LAUNCH_BOUNDS() must be 2 or 3 integer constants"_err_en_US
);
4236 } else if (auto *subp
{currScope().symbol()
4237 ? currScope().symbol()->detailsIf
<SubprogramDetails
>()
4239 if (subp
->cudaLaunchBounds().empty()) {
4240 subp
->set_cudaLaunchBounds(std::move(bounds
));
4242 Say(currStmtSource().value(),
4243 "LAUNCH_BOUNDS() may only appear once"_err_en_US
);
4248 void SubprogramVisitor::Post(const parser::PrefixSpec::Cluster_Dims
&x
) {
4249 std::vector
<std::int64_t> dims
;
4251 for (const auto &sicx
: x
.v
) {
4252 if (auto value
{evaluate::ToInt64(EvaluateExpr(sicx
))}) {
4253 dims
.push_back(*value
);
4258 if (!ok
|| dims
.size() != 3) {
4259 Say(currStmtSource().value(),
4260 "Operands of CLUSTER_DIMS() must be three integer constants"_err_en_US
);
4261 } else if (auto *subp
{currScope().symbol()
4262 ? currScope().symbol()->detailsIf
<SubprogramDetails
>()
4264 if (subp
->cudaClusterDims().empty()) {
4265 subp
->set_cudaClusterDims(std::move(dims
));
4267 Say(currStmtSource().value(),
4268 "CLUSTER_DIMS() may only appear once"_err_en_US
);
4273 static bool HasModulePrefix(const std::list
<parser::PrefixSpec
> &prefixes
) {
4274 for (const auto &prefix
: prefixes
) {
4275 if (std::holds_alternative
<parser::PrefixSpec::Module
>(prefix
.u
)) {
4282 bool SubprogramVisitor::Pre(const parser::InterfaceBody::Subroutine
&x
) {
4283 const auto &stmtTuple
{
4284 std::get
<parser::Statement
<parser::SubroutineStmt
>>(x
.t
).statement
.t
};
4285 return BeginSubprogram(std::get
<parser::Name
>(stmtTuple
),
4286 Symbol::Flag::Subroutine
,
4287 HasModulePrefix(std::get
<std::list
<parser::PrefixSpec
>>(stmtTuple
)));
4289 void SubprogramVisitor::Post(const parser::InterfaceBody::Subroutine
&x
) {
4290 const auto &stmt
{std::get
<parser::Statement
<parser::SubroutineStmt
>>(x
.t
)};
4291 EndSubprogram(stmt
.source
,
4292 &std::get
<std::optional
<parser::LanguageBindingSpec
>>(stmt
.statement
.t
));
4294 bool SubprogramVisitor::Pre(const parser::InterfaceBody::Function
&x
) {
4295 const auto &stmtTuple
{
4296 std::get
<parser::Statement
<parser::FunctionStmt
>>(x
.t
).statement
.t
};
4297 return BeginSubprogram(std::get
<parser::Name
>(stmtTuple
),
4298 Symbol::Flag::Function
,
4299 HasModulePrefix(std::get
<std::list
<parser::PrefixSpec
>>(stmtTuple
)));
4301 void SubprogramVisitor::Post(const parser::InterfaceBody::Function
&x
) {
4302 const auto &stmt
{std::get
<parser::Statement
<parser::FunctionStmt
>>(x
.t
)};
4303 const auto &maybeSuffix
{
4304 std::get
<std::optional
<parser::Suffix
>>(stmt
.statement
.t
)};
4305 EndSubprogram(stmt
.source
, maybeSuffix
? &maybeSuffix
->binding
: nullptr);
4308 bool SubprogramVisitor::Pre(const parser::SubroutineStmt
&stmt
) {
4310 Walk(std::get
<std::list
<parser::PrefixSpec
>>(stmt
.t
));
4311 Walk(std::get
<parser::Name
>(stmt
.t
));
4312 Walk(std::get
<std::list
<parser::DummyArg
>>(stmt
.t
));
4313 // Don't traverse the LanguageBindingSpec now; it's deferred to EndSubprogram.
4314 Symbol
&symbol
{PostSubprogramStmt()};
4315 SubprogramDetails
&details
{symbol
.get
<SubprogramDetails
>()};
4316 for (const auto &dummyArg
: std::get
<std::list
<parser::DummyArg
>>(stmt
.t
)) {
4317 if (const auto *dummyName
{std::get_if
<parser::Name
>(&dummyArg
.u
)}) {
4318 CreateDummyArgument(details
, *dummyName
);
4320 details
.add_alternateReturn();
4325 bool SubprogramVisitor::Pre(const parser::FunctionStmt
&) {
4326 FuncResultStack::FuncInfo
&info
{DEREF(funcResultStack().Top())};
4327 CHECK(!info
.inFunctionStmt
);
4328 info
.inFunctionStmt
= true;
4329 if (auto at
{currStmtSource()}) {
4332 return BeginAttrs();
4334 bool SubprogramVisitor::Pre(const parser::EntryStmt
&) { return BeginAttrs(); }
4336 void SubprogramVisitor::Post(const parser::FunctionStmt
&stmt
) {
4337 const auto &name
{std::get
<parser::Name
>(stmt
.t
)};
4338 Symbol
&symbol
{PostSubprogramStmt()};
4339 SubprogramDetails
&details
{symbol
.get
<SubprogramDetails
>()};
4340 for (const auto &dummyName
: std::get
<std::list
<parser::Name
>>(stmt
.t
)) {
4341 CreateDummyArgument(details
, dummyName
);
4343 const parser::Name
*funcResultName
;
4344 FuncResultStack::FuncInfo
&info
{DEREF(funcResultStack().Top())};
4345 CHECK(info
.inFunctionStmt
);
4346 info
.inFunctionStmt
= false;
4347 bool distinctResultName
{
4348 info
.resultName
&& info
.resultName
->source
!= name
.source
};
4349 if (distinctResultName
) {
4350 // Note that RESULT is ignored if it has the same name as the function.
4351 // The symbol created by PushScope() is retained as a place-holder
4352 // for error detection.
4353 funcResultName
= info
.resultName
;
4355 EraseSymbol(name
); // was added by PushScope()
4356 funcResultName
= &name
;
4358 if (details
.isFunction()) {
4359 CHECK(context().HasError(currScope().symbol()));
4361 // RESULT(x) can be the same explicitly-named RESULT(x) as an ENTRY
4363 Symbol
*result
{nullptr};
4364 if (distinctResultName
) {
4365 if (auto iter
{currScope().find(funcResultName
->source
)};
4366 iter
!= currScope().end()) {
4367 Symbol
&entryResult
{*iter
->second
};
4368 if (IsFunctionResult(entryResult
)) {
4369 result
= &entryResult
;
4374 Resolve(*funcResultName
, *result
);
4376 // add function result to function scope
4377 EntityDetails funcResultDetails
;
4378 funcResultDetails
.set_funcResult(true);
4379 result
= &MakeSymbol(*funcResultName
, std::move(funcResultDetails
));
4381 info
.resultSymbol
= result
;
4382 details
.set_result(*result
);
4385 if (info
.resultName
&& !distinctResultName
) {
4386 context().Warn(common::UsageWarning::HomonymousResult
,
4387 info
.resultName
->source
,
4388 "The function name should not appear in RESULT; references to '%s' "
4389 "inside the function will be considered as references to the "
4390 "result only"_warn_en_US
,
4392 // RESULT name was ignored above, the only side effect from doing so will be
4393 // the inability to make recursive calls. The related parser::Name is still
4394 // resolved to the created function result symbol because every parser::Name
4395 // should be resolved to avoid internal errors.
4396 Resolve(*info
.resultName
, info
.resultSymbol
);
4398 name
.symbol
= &symbol
; // must not be function result symbol
4399 // Clear the RESULT() name now in case an ENTRY statement in the implicit-part
4400 // has a RESULT() suffix.
4401 info
.resultName
= nullptr;
4404 Symbol
&SubprogramVisitor::PostSubprogramStmt() {
4405 Symbol
&symbol
{*currScope().symbol()};
4406 SetExplicitAttrs(symbol
, EndAttrs());
4407 if (symbol
.attrs().test(Attr::MODULE
)) {
4408 symbol
.attrs().set(Attr::EXTERNAL
, false);
4409 symbol
.implicitAttrs().set(Attr::EXTERNAL
, false);
4414 void SubprogramVisitor::Post(const parser::EntryStmt
&stmt
) {
4415 if (const auto &suffix
{std::get
<std::optional
<parser::Suffix
>>(stmt
.t
)}) {
4416 Walk(suffix
->binding
);
4418 PostEntryStmt(stmt
);
4422 void SubprogramVisitor::CreateDummyArgument(
4423 SubprogramDetails
&details
, const parser::Name
&name
) {
4424 Symbol
*dummy
{FindInScope(name
)};
4426 if (IsDummy(*dummy
)) {
4427 if (dummy
->test(Symbol::Flag::EntryDummyArgument
)) {
4428 dummy
->set(Symbol::Flag::EntryDummyArgument
, false);
4431 "'%s' appears more than once as a dummy argument name in this subprogram"_err_en_US
,
4436 SayWithDecl(name
, *dummy
,
4437 "'%s' may not appear as a dummy argument name in this subprogram"_err_en_US
);
4441 dummy
= &MakeSymbol(name
, EntityDetails
{true});
4443 details
.add_dummyArg(DEREF(dummy
));
4446 void SubprogramVisitor::CreateEntry(
4447 const parser::EntryStmt
&stmt
, Symbol
&subprogram
) {
4448 const auto &entryName
{std::get
<parser::Name
>(stmt
.t
)};
4449 Scope
&outer
{currScope().parent()};
4450 Symbol::Flag subpFlag
{subprogram
.test(Symbol::Flag::Function
)
4451 ? Symbol::Flag::Function
4452 : Symbol::Flag::Subroutine
};
4454 const auto &suffix
{std::get
<std::optional
<parser::Suffix
>>(stmt
.t
)};
4455 bool hasGlobalBindingName
{outer
.IsGlobal() && suffix
&& suffix
->binding
&&
4456 std::get
<std::optional
<parser::ScalarDefaultCharConstantExpr
>>(
4459 if (!hasGlobalBindingName
) {
4460 if (Symbol
* extant
{FindSymbol(outer
, entryName
)}) {
4461 if (!HandlePreviousCalls(entryName
, *extant
, subpFlag
)) {
4462 if (outer
.IsTopLevel()) {
4464 "'%s' is already defined as a global identifier"_err_en_US
,
4465 *extant
, "Previous definition of '%s'"_en_US
);
4467 SayAlreadyDeclared(entryName
, *extant
);
4471 attrs
= extant
->attrs();
4474 std::optional
<SourceName
> distinctResultName
;
4475 if (suffix
&& suffix
->resultName
&&
4476 suffix
->resultName
->source
!= entryName
.source
) {
4477 distinctResultName
= suffix
->resultName
->source
;
4479 if (outer
.IsModule() && !attrs
.test(Attr::PRIVATE
)) {
4480 attrs
.set(Attr::PUBLIC
);
4482 Symbol
*entrySymbol
{nullptr};
4483 if (hasGlobalBindingName
) {
4484 // Hide the entry's symbol in a new anonymous global scope so
4485 // that its name doesn't clash with anything.
4486 Symbol
&symbol
{MakeSymbol(outer
, context().GetTempName(outer
), Attrs
{})};
4487 symbol
.set_details(MiscDetails
{MiscDetails::Kind::ScopeName
});
4488 Scope
&hidden
{outer
.MakeScope(Scope::Kind::Global
, &symbol
)};
4489 entrySymbol
= &MakeSymbol(hidden
, entryName
.source
, attrs
);
4491 entrySymbol
= FindInScope(outer
, entryName
.source
);
4493 if (auto *generic
{entrySymbol
->detailsIf
<GenericDetails
>()}) {
4494 if (auto *specific
{generic
->specific()}) {
4495 // Forward reference to ENTRY from a generic interface
4496 entrySymbol
= specific
;
4497 CheckDuplicatedAttrs(entryName
.source
, *entrySymbol
, attrs
);
4498 SetExplicitAttrs(*entrySymbol
, attrs
);
4502 entrySymbol
= &MakeSymbol(outer
, entryName
.source
, attrs
);
4505 SubprogramDetails entryDetails
;
4506 entryDetails
.set_entryScope(currScope());
4507 entrySymbol
->set(subpFlag
);
4508 if (subpFlag
== Symbol::Flag::Function
) {
4509 Symbol
*result
{nullptr};
4510 EntityDetails resultDetails
;
4511 resultDetails
.set_funcResult(true);
4512 if (distinctResultName
) {
4513 // An explicit RESULT() can also be an explicit RESULT()
4514 // of the function or another ENTRY.
4515 if (auto iter
{currScope().find(suffix
->resultName
->source
)};
4516 iter
!= currScope().end()) {
4517 result
= &*iter
->second
;
4521 &MakeSymbol(*distinctResultName
, Attrs
{}, std::move(resultDetails
));
4522 } else if (!result
->has
<EntityDetails
>()) {
4523 Say(*distinctResultName
,
4524 "ENTRY cannot have RESULT(%s) that is not a variable"_err_en_US
,
4525 *distinctResultName
)
4526 .Attach(result
->name(), "Existing declaration of '%s'"_en_US
,
4531 Resolve(*suffix
->resultName
, *result
);
4534 result
= &MakeSymbol(entryName
.source
, Attrs
{}, std::move(resultDetails
));
4537 entryDetails
.set_result(*result
);
4540 if (subpFlag
== Symbol::Flag::Subroutine
|| distinctResultName
) {
4541 Symbol
&assoc
{MakeSymbol(entryName
.source
)};
4542 assoc
.set_details(HostAssocDetails
{*entrySymbol
});
4543 assoc
.set(Symbol::Flag::Subroutine
);
4545 Resolve(entryName
, *entrySymbol
);
4546 std::set
<SourceName
> dummies
;
4547 for (const auto &dummyArg
: std::get
<std::list
<parser::DummyArg
>>(stmt
.t
)) {
4548 if (const auto *dummyName
{std::get_if
<parser::Name
>(&dummyArg
.u
)}) {
4549 auto pair
{dummies
.insert(dummyName
->source
)};
4552 "'%s' appears more than once as a dummy argument name in this ENTRY statement"_err_en_US
,
4556 Symbol
*dummy
{FindInScope(*dummyName
)};
4558 if (!IsDummy(*dummy
)) {
4559 evaluate::AttachDeclaration(
4561 "'%s' may not appear as a dummy argument name in this ENTRY statement"_err_en_US
,
4567 dummy
= &MakeSymbol(*dummyName
, EntityDetails
{true});
4568 dummy
->set(Symbol::Flag::EntryDummyArgument
);
4570 entryDetails
.add_dummyArg(DEREF(dummy
));
4571 } else if (subpFlag
== Symbol::Flag::Function
) { // C1573
4573 "ENTRY in a function may not have an alternate return dummy argument"_err_en_US
);
4576 entryDetails
.add_alternateReturn();
4579 entrySymbol
->set_details(std::move(entryDetails
));
4582 void SubprogramVisitor::PostEntryStmt(const parser::EntryStmt
&stmt
) {
4583 // The entry symbol should have already been created and resolved
4584 // in CreateEntry(), called by BeginSubprogram(), with one exception (below).
4585 const auto &name
{std::get
<parser::Name
>(stmt
.t
)};
4586 Scope
&inclusiveScope
{InclusiveScope()};
4588 if (inclusiveScope
.kind() != Scope::Kind::Subprogram
) {
4590 "ENTRY '%s' may appear only in a subroutine or function"_err_en_US
,
4592 } else if (FindSeparateModuleSubprogramInterface(inclusiveScope
.symbol())) {
4594 "ENTRY '%s' may not appear in a separate module procedure"_err_en_US
,
4597 // C1571 - entry is nested, so was not put into the program tree; error
4598 // is emitted from MiscChecker in semantics.cpp.
4602 Symbol
&entrySymbol
{*name
.symbol
};
4603 if (context().HasError(entrySymbol
)) {
4606 if (!entrySymbol
.has
<SubprogramDetails
>()) {
4607 SayAlreadyDeclared(name
, entrySymbol
);
4610 SubprogramDetails
&entryDetails
{entrySymbol
.get
<SubprogramDetails
>()};
4611 CHECK(entryDetails
.entryScope() == &inclusiveScope
);
4612 SetCUDADataAttr(name
.source
, entrySymbol
, cudaDataAttr());
4613 entrySymbol
.attrs() |= GetAttrs();
4614 SetBindNameOn(entrySymbol
);
4615 for (const auto &dummyArg
: std::get
<std::list
<parser::DummyArg
>>(stmt
.t
)) {
4616 if (const auto *dummyName
{std::get_if
<parser::Name
>(&dummyArg
.u
)}) {
4617 if (Symbol
* dummy
{FindInScope(*dummyName
)}) {
4618 if (dummy
->test(Symbol::Flag::EntryDummyArgument
)) {
4619 const auto *subp
{dummy
->detailsIf
<SubprogramDetails
>()};
4620 if (subp
&& subp
->isInterface()) { // ok
4621 } else if (!dummy
->has
<EntityDetails
>() &&
4622 !dummy
->has
<ObjectEntityDetails
>() &&
4623 !dummy
->has
<ProcEntityDetails
>()) {
4624 SayWithDecl(*dummyName
, *dummy
,
4625 "ENTRY dummy argument '%s' was previously declared as an item that may not be used as a dummy argument"_err_en_US
);
4627 dummy
->set(Symbol::Flag::EntryDummyArgument
, false);
4634 Symbol
*ScopeHandler::FindSeparateModuleProcedureInterface(
4635 const parser::Name
&name
) {
4636 auto *symbol
{FindSymbol(name
)};
4637 if (symbol
&& symbol
->has
<SubprogramNameDetails
>()) {
4638 const Scope
*parent
{nullptr};
4639 if (currScope().IsSubmodule()) {
4640 parent
= currScope().symbol()->get
<ModuleDetails
>().parent();
4642 symbol
= parent
? FindSymbol(*parent
, name
) : nullptr;
4645 if (auto *generic
{symbol
->detailsIf
<GenericDetails
>()}) {
4646 symbol
= generic
->specific();
4649 if (const Symbol
* defnIface
{FindSeparateModuleSubprogramInterface(symbol
)}) {
4650 // Error recovery in case of multiple definitions
4651 symbol
= const_cast<Symbol
*>(defnIface
);
4653 if (!IsSeparateModuleProcedureInterface(symbol
)) {
4654 Say(name
, "'%s' was not declared a separate module procedure"_err_en_US
);
4660 // A subprogram declared with MODULE PROCEDURE
4661 bool SubprogramVisitor::BeginMpSubprogram(const parser::Name
&name
) {
4662 Symbol
*symbol
{FindSeparateModuleProcedureInterface(name
)};
4666 if (symbol
->owner() == currScope() && symbol
->scope()) {
4667 // This is a MODULE PROCEDURE whose interface appears in its host.
4668 // Convert the module procedure's interface into a subprogram.
4669 SetScope(DEREF(symbol
->scope()));
4670 symbol
->get
<SubprogramDetails
>().set_isInterface(false);
4671 name
.symbol
= symbol
;
4673 // Copy the interface into a new subprogram scope.
4675 Symbol
&newSymbol
{MakeSymbol(name
, SubprogramDetails
{})};
4676 PushScope(Scope::Kind::Subprogram
, &newSymbol
);
4677 auto &newSubprogram
{newSymbol
.get
<SubprogramDetails
>()};
4678 newSubprogram
.set_moduleInterface(*symbol
);
4679 auto &subprogram
{symbol
->get
<SubprogramDetails
>()};
4680 if (const auto *name
{subprogram
.bindName()}) {
4681 newSubprogram
.set_bindName(std::string
{*name
});
4683 newSymbol
.attrs() |= symbol
->attrs();
4684 newSymbol
.set(symbol
->test(Symbol::Flag::Subroutine
)
4685 ? Symbol::Flag::Subroutine
4686 : Symbol::Flag::Function
);
4687 MapSubprogramToNewSymbols(*symbol
, newSymbol
, currScope());
4692 // A subprogram or interface declared with SUBROUTINE or FUNCTION
4693 bool SubprogramVisitor::BeginSubprogram(const parser::Name
&name
,
4694 Symbol::Flag subpFlag
, bool hasModulePrefix
,
4695 const parser::LanguageBindingSpec
*bindingSpec
,
4696 const ProgramTree::EntryStmtList
*entryStmts
) {
4698 if (hasModulePrefix
&& !currScope().IsModule() &&
4699 !currScope().IsSubmodule()) { // C1547
4701 "'%s' is a MODULE procedure which must be declared within a "
4702 "MODULE or SUBMODULE"_err_en_US
);
4703 // Don't return here because it can be useful to have the scope set for
4704 // other semantic checks run before we print the errors
4707 Symbol
*moduleInterface
{nullptr};
4708 if (isValid
&& hasModulePrefix
&& !inInterfaceBlock()) {
4709 moduleInterface
= FindSeparateModuleProcedureInterface(name
);
4710 if (moduleInterface
&& &moduleInterface
->owner() == &currScope()) {
4711 // Subprogram is MODULE FUNCTION or MODULE SUBROUTINE with an interface
4712 // previously defined in the same scope.
4713 if (GenericDetails
*
4714 generic
{DEREF(FindSymbol(name
)).detailsIf
<GenericDetails
>()}) {
4715 generic
->clear_specific();
4716 name
.symbol
= nullptr;
4723 PushSubprogramScope(name
, subpFlag
, bindingSpec
, hasModulePrefix
)};
4724 if (moduleInterface
) {
4725 newSymbol
.get
<SubprogramDetails
>().set_moduleInterface(*moduleInterface
);
4726 if (moduleInterface
->attrs().test(Attr::PRIVATE
)) {
4727 SetImplicitAttr(newSymbol
, Attr::PRIVATE
);
4728 } else if (moduleInterface
->attrs().test(Attr::PUBLIC
)) {
4729 SetImplicitAttr(newSymbol
, Attr::PUBLIC
);
4733 for (const auto &ref
: *entryStmts
) {
4734 CreateEntry(*ref
, newSymbol
);
4740 void SubprogramVisitor::HandleLanguageBinding(Symbol
*symbol
,
4741 std::optional
<parser::CharBlock
> stmtSource
,
4742 const std::optional
<parser::LanguageBindingSpec
> *binding
) {
4743 if (binding
&& *binding
&& symbol
) {
4744 // Finally process the BIND(C,NAME=name) now that symbols in the name
4745 // expression will resolve to local names if needed.
4746 auto flagRestorer
{common::ScopedSet(inSpecificationPart_
, false)};
4747 auto originalStmtSource
{messageHandler().currStmtSource()};
4748 messageHandler().set_currStmtSource(stmtSource
);
4751 SetBindNameOn(*symbol
);
4752 symbol
->attrs() |= EndAttrs();
4753 messageHandler().set_currStmtSource(originalStmtSource
);
4757 void SubprogramVisitor::EndSubprogram(
4758 std::optional
<parser::CharBlock
> stmtSource
,
4759 const std::optional
<parser::LanguageBindingSpec
> *binding
,
4760 const ProgramTree::EntryStmtList
*entryStmts
) {
4761 HandleLanguageBinding(currScope().symbol(), stmtSource
, binding
);
4763 for (const auto &ref
: *entryStmts
) {
4764 const parser::EntryStmt
&entryStmt
{*ref
};
4765 if (const auto &suffix
{
4766 std::get
<std::optional
<parser::Suffix
>>(entryStmt
.t
)}) {
4767 const auto &name
{std::get
<parser::Name
>(entryStmt
.t
)};
4768 HandleLanguageBinding(name
.symbol
, name
.source
, &suffix
->binding
);
4772 if (inInterfaceBlock() && currScope().symbol()) {
4773 DeclaredPossibleSpecificProc(*currScope().symbol());
4778 bool SubprogramVisitor::HandlePreviousCalls(
4779 const parser::Name
&name
, Symbol
&symbol
, Symbol::Flag subpFlag
) {
4780 // If the extant symbol is a generic, check its homonymous specific
4781 // procedure instead if it has one.
4782 if (auto *generic
{symbol
.detailsIf
<GenericDetails
>()}) {
4783 return generic
->specific() &&
4784 HandlePreviousCalls(name
, *generic
->specific(), subpFlag
);
4785 } else if (const auto *proc
{symbol
.detailsIf
<ProcEntityDetails
>()}; proc
&&
4787 !symbol
.attrs().HasAny(Attrs
{Attr::INTRINSIC
, Attr::POINTER
})) {
4788 // There's a symbol created for previous calls to this subprogram or
4789 // ENTRY's name. We have to replace that symbol in situ to avoid the
4790 // obligation to rewrite symbol pointers in the parse tree.
4791 if (!symbol
.test(subpFlag
)) {
4792 auto other
{subpFlag
== Symbol::Flag::Subroutine
4793 ? Symbol::Flag::Function
4794 : Symbol::Flag::Subroutine
};
4795 // External statements issue an explicit EXTERNAL attribute.
4796 if (symbol
.attrs().test(Attr::EXTERNAL
) &&
4797 !symbol
.implicitAttrs().test(Attr::EXTERNAL
)) {
4798 // Warn if external statement previously declared.
4799 context().Warn(common::LanguageFeature::RedundantAttribute
, name
.source
,
4800 "EXTERNAL attribute was already specified on '%s'"_warn_en_US
,
4802 } else if (symbol
.test(other
)) {
4804 subpFlag
== Symbol::Flag::Function
4805 ? "'%s' was previously called as a subroutine"_err_en_US
4806 : "'%s' was previously called as a function"_err_en_US
,
4807 symbol
, "Previous call of '%s'"_en_US
);
4809 symbol
.set(subpFlag
);
4812 EntityDetails entity
;
4814 entity
.set_type(*proc
->type());
4816 symbol
.details() = std::move(entity
);
4819 return symbol
.has
<UnknownDetails
>() || symbol
.has
<SubprogramNameDetails
>();
4823 void SubprogramVisitor::CheckExtantProc(
4824 const parser::Name
&name
, Symbol::Flag subpFlag
) {
4825 if (auto *prev
{FindSymbol(name
)}) {
4826 if (IsDummy(*prev
)) {
4827 } else if (auto *entity
{prev
->detailsIf
<EntityDetails
>()};
4828 IsPointer(*prev
) && entity
&& !entity
->type()) {
4829 // POINTER attribute set before interface
4830 } else if (inInterfaceBlock() && currScope() != prev
->owner()) {
4831 // Procedures in an INTERFACE block do not resolve to symbols
4832 // in scopes between the global scope and the current scope.
4833 } else if (!HandlePreviousCalls(name
, *prev
, subpFlag
)) {
4834 SayAlreadyDeclared(name
, *prev
);
4839 Symbol
&SubprogramVisitor::PushSubprogramScope(const parser::Name
&name
,
4840 Symbol::Flag subpFlag
, const parser::LanguageBindingSpec
*bindingSpec
,
4841 bool hasModulePrefix
) {
4842 Symbol
*symbol
{GetSpecificFromGeneric(name
)};
4844 if (bindingSpec
&& currScope().IsGlobal() &&
4845 std::get
<std::optional
<parser::ScalarDefaultCharConstantExpr
>>(
4848 // Create this new top-level subprogram with a binding label
4849 // in a new global scope, so that its symbol's name won't clash
4850 // with another symbol that has a distinct binding label.
4851 PushScope(Scope::Kind::Global
,
4852 &MakeSymbol(context().GetTempName(currScope()), Attrs
{},
4853 MiscDetails
{MiscDetails::Kind::ScopeName
}));
4855 CheckExtantProc(name
, subpFlag
);
4856 symbol
= &MakeSymbol(name
, SubprogramDetails
{});
4858 symbol
->ReplaceName(name
.source
);
4859 symbol
->set(subpFlag
);
4860 PushScope(Scope::Kind::Subprogram
, symbol
);
4861 if (subpFlag
== Symbol::Flag::Function
) {
4862 funcResultStack().Push(currScope(), name
.source
);
4864 if (inInterfaceBlock()) {
4865 auto &details
{symbol
->get
<SubprogramDetails
>()};
4866 details
.set_isInterface();
4868 SetExplicitAttr(*symbol
, Attr::ABSTRACT
);
4869 } else if (hasModulePrefix
) {
4870 SetExplicitAttr(*symbol
, Attr::MODULE
);
4872 MakeExternal(*symbol
);
4875 Symbol
&genericSymbol
{GetGenericSymbol()};
4876 if (auto *details
{genericSymbol
.detailsIf
<GenericDetails
>()}) {
4877 details
->AddSpecificProc(*symbol
, name
.source
);
4879 CHECK(context().HasError(genericSymbol
));
4882 set_inheritFromParent(false); // interfaces don't inherit, even if MODULE
4884 if (Symbol
* found
{FindSymbol(name
)};
4885 found
&& found
->has
<HostAssocDetails
>()) {
4886 found
->set(subpFlag
); // PushScope() created symbol
4891 void SubprogramVisitor::PushBlockDataScope(const parser::Name
&name
) {
4892 if (auto *prev
{FindSymbol(name
)}) {
4893 if (prev
->attrs().test(Attr::EXTERNAL
) && prev
->has
<ProcEntityDetails
>()) {
4894 if (prev
->test(Symbol::Flag::Subroutine
) ||
4895 prev
->test(Symbol::Flag::Function
)) {
4896 Say2(name
, "BLOCK DATA '%s' has been called"_err_en_US
, *prev
,
4897 "Previous call of '%s'"_en_US
);
4902 if (name
.source
.empty()) {
4903 // Don't let unnamed BLOCK DATA conflict with unnamed PROGRAM
4904 PushScope(Scope::Kind::BlockData
, nullptr);
4906 PushScope(Scope::Kind::BlockData
, &MakeSymbol(name
, SubprogramDetails
{}));
4910 // If name is a generic, return specific subprogram with the same name.
4911 Symbol
*SubprogramVisitor::GetSpecificFromGeneric(const parser::Name
&name
) {
4912 // Search for the name but don't resolve it
4913 if (auto *symbol
{currScope().FindSymbol(name
.source
)}) {
4914 if (symbol
->has
<SubprogramNameDetails
>()) {
4915 if (inInterfaceBlock()) {
4916 // Subtle: clear any MODULE flag so that the new interface
4917 // symbol doesn't inherit it and ruin the ability to check it.
4918 symbol
->attrs().reset(Attr::MODULE
);
4920 } else if (auto *details
{symbol
->detailsIf
<GenericDetails
>()}) {
4921 // found generic, want specific procedure
4922 auto *specific
{details
->specific()};
4924 if (inInterfaceBlock()) {
4926 // Defining an interface in a generic of the same name which is
4927 // already shadowing another procedure. In some cases, the shadowed
4928 // procedure is about to be replaced.
4929 if (specific
->has
<SubprogramNameDetails
>() &&
4930 specific
->attrs().test(Attr::MODULE
)) {
4931 // The shadowed procedure is a separate module procedure that is
4932 // actually defined later in this (sub)module.
4933 // Define its interface now as a new symbol.
4934 moduleAttr
.set(Attr::MODULE
);
4936 } else if (&specific
->owner() != &symbol
->owner()) {
4937 // The shadowed procedure was from an enclosing scope and will be
4938 // overridden by this interface definition.
4942 details
->clear_specific();
4944 } else if (const auto *dType
{details
->derivedType()}) {
4945 if (&dType
->owner() != &symbol
->owner()) {
4946 // The shadowed derived type was from an enclosing scope and
4947 // will be overridden by this interface definition.
4948 details
->clear_derivedType();
4953 specific
= &currScope().MakeSymbol(
4954 name
.source
, std::move(moduleAttr
), SubprogramDetails
{});
4955 if (details
->derivedType()) {
4956 // A specific procedure with the same name as a derived type
4957 SayAlreadyDeclared(name
, *details
->derivedType());
4959 details
->set_specific(Resolve(name
, *specific
));
4961 } else if (isGeneric()) {
4962 SayAlreadyDeclared(name
, *specific
);
4964 if (specific
->has
<SubprogramNameDetails
>()) {
4965 specific
->set_details(Details
{SubprogramDetails
{}});
4973 // DeclarationVisitor implementation
4975 bool DeclarationVisitor::BeginDecl() {
4976 BeginDeclTypeSpec();
4978 return BeginAttrs();
4980 void DeclarationVisitor::EndDecl() {
4986 bool DeclarationVisitor::CheckUseError(const parser::Name
&name
) {
4987 return HadUseError(context(), name
.source
, name
.symbol
);
4990 // Report error if accessibility of symbol doesn't match isPrivate.
4991 void DeclarationVisitor::CheckAccessibility(
4992 const SourceName
&name
, bool isPrivate
, Symbol
&symbol
) {
4993 if (symbol
.attrs().test(Attr::PRIVATE
) != isPrivate
) {
4995 "'%s' does not have the same accessibility as its previous declaration"_err_en_US
,
4996 symbol
, "Previous declaration of '%s'"_en_US
);
5000 bool DeclarationVisitor::Pre(const parser::TypeDeclarationStmt
&x
) {
5002 // If INTRINSIC appears as an attr-spec, handle it now as if the
5003 // names had appeared on an INTRINSIC attribute statement beforehand.
5004 for (const auto &attr
: std::get
<std::list
<parser::AttrSpec
>>(x
.t
)) {
5005 if (std::holds_alternative
<parser::Intrinsic
>(attr
.u
)) {
5006 for (const auto &decl
: std::get
<std::list
<parser::EntityDecl
>>(x
.t
)) {
5007 DeclareIntrinsic(parser::GetFirstName(decl
));
5014 void DeclarationVisitor::Post(const parser::TypeDeclarationStmt
&) {
5018 void DeclarationVisitor::Post(const parser::DimensionStmt::Declaration
&x
) {
5019 DeclareObjectEntity(std::get
<parser::Name
>(x
.t
));
5021 void DeclarationVisitor::Post(const parser::CodimensionDecl
&x
) {
5022 DeclareObjectEntity(std::get
<parser::Name
>(x
.t
));
5025 bool DeclarationVisitor::Pre(const parser::Initialization
&) {
5026 // Defer inspection of initializers to Initialization() so that the
5027 // symbol being initialized will be available within the initialization
5032 void DeclarationVisitor::Post(const parser::EntityDecl
&x
) {
5033 const auto &name
{std::get
<parser::ObjectName
>(x
.t
)};
5034 Attrs attrs
{attrs_
? HandleSaveName(name
.source
, *attrs_
) : Attrs
{}};
5035 attrs
.set(Attr::INTRINSIC
, false); // dealt with in Pre(TypeDeclarationStmt)
5036 Symbol
&symbol
{DeclareUnknownEntity(name
, attrs
)};
5037 symbol
.ReplaceName(name
.source
);
5038 SetCUDADataAttr(name
.source
, symbol
, cudaDataAttr());
5039 if (const auto &init
{std::get
<std::optional
<parser::Initialization
>>(x
.t
)}) {
5040 ConvertToObjectEntity(symbol
) || ConvertToProcEntity(symbol
);
5042 Symbol::Flag::EntryDummyArgument
, false); // forestall excessive errors
5043 Initialization(name
, *init
, false);
5044 } else if (attrs
.test(Attr::PARAMETER
)) { // C882, C883
5045 Say(name
, "Missing initialization for parameter '%s'"_err_en_US
);
5047 if (auto *scopeSymbol
{currScope().symbol()}) {
5048 if (auto *details
{scopeSymbol
->detailsIf
<DerivedTypeDetails
>()}) {
5049 if (details
->isDECStructure()) {
5050 details
->add_component(symbol
);
5056 void DeclarationVisitor::Post(const parser::PointerDecl
&x
) {
5057 const auto &name
{std::get
<parser::Name
>(x
.t
)};
5058 if (const auto &deferredShapeSpecs
{
5059 std::get
<std::optional
<parser::DeferredShapeSpecList
>>(x
.t
)}) {
5060 CHECK(arraySpec().empty());
5062 set_arraySpec(AnalyzeDeferredShapeSpecList(context(), *deferredShapeSpecs
));
5063 Symbol
&symbol
{DeclareObjectEntity(name
, Attrs
{Attr::POINTER
})};
5064 symbol
.ReplaceName(name
.source
);
5067 if (const auto *symbol
{FindInScope(name
)}) {
5068 const auto *subp
{symbol
->detailsIf
<SubprogramDetails
>()};
5069 if (!symbol
->has
<UseDetails
>() && // error caught elsewhere
5070 !symbol
->has
<ObjectEntityDetails
>() &&
5071 !symbol
->has
<ProcEntityDetails
>() &&
5072 !symbol
->CanReplaceDetails(ObjectEntityDetails
{}) &&
5073 !symbol
->CanReplaceDetails(ProcEntityDetails
{}) &&
5074 !(subp
&& subp
->isInterface())) {
5075 Say(name
, "'%s' cannot have the POINTER attribute"_err_en_US
);
5078 HandleAttributeStmt(Attr::POINTER
, std::get
<parser::Name
>(x
.t
));
5082 bool DeclarationVisitor::Pre(const parser::BindEntity
&x
) {
5083 auto kind
{std::get
<parser::BindEntity::Kind
>(x
.t
)};
5084 auto &name
{std::get
<parser::Name
>(x
.t
)};
5086 if (kind
== parser::BindEntity::Kind::Object
) {
5087 symbol
= &HandleAttributeStmt(Attr::BIND_C
, name
);
5089 symbol
= &MakeCommonBlockSymbol(name
);
5090 SetExplicitAttr(*symbol
, Attr::BIND_C
);
5093 // Some entities such as named constant or module name need to checked
5094 // elsewhere. This is to skip the ICE caused by setting Bind name for non-name
5095 // things such as data type and also checks for procedures.
5096 if (symbol
->has
<CommonBlockDetails
>() || symbol
->has
<ObjectEntityDetails
>() ||
5097 symbol
->has
<EntityDetails
>()) {
5098 SetBindNameOn(*symbol
);
5101 "Only variable and named common block can be in BIND statement"_err_en_US
);
5105 bool DeclarationVisitor::Pre(const parser::OldParameterStmt
&x
) {
5106 inOldStyleParameterStmt_
= true;
5108 inOldStyleParameterStmt_
= false;
5111 bool DeclarationVisitor::Pre(const parser::NamedConstantDef
&x
) {
5112 auto &name
{std::get
<parser::NamedConstant
>(x
.t
).v
};
5113 auto &symbol
{HandleAttributeStmt(Attr::PARAMETER
, name
)};
5114 ConvertToObjectEntity(symbol
);
5115 auto *details
{symbol
.detailsIf
<ObjectEntityDetails
>()};
5116 if (!details
|| symbol
.test(Symbol::Flag::CrayPointer
) ||
5117 symbol
.test(Symbol::Flag::CrayPointee
)) {
5119 name
, symbol
, "PARAMETER attribute not allowed on '%s'"_err_en_US
);
5122 const auto &expr
{std::get
<parser::ConstantExpr
>(x
.t
)};
5123 if (details
->init() || symbol
.test(Symbol::Flag::InDataStmt
)) {
5124 Say(name
, "Named constant '%s' already has a value"_err_en_US
);
5126 if (inOldStyleParameterStmt_
) {
5127 // non-standard extension PARAMETER statement (no parentheses)
5129 auto folded
{EvaluateExpr(expr
)};
5130 if (details
->type()) {
5131 SayWithDecl(name
, symbol
,
5132 "Alternative style PARAMETER '%s' must not already have an explicit type"_err_en_US
);
5133 } else if (folded
) {
5134 auto at
{expr
.thing
.value().source
};
5135 if (evaluate::IsActuallyConstant(*folded
)) {
5136 if (const auto *type
{currScope().GetType(*folded
)}) {
5137 if (type
->IsPolymorphic()) {
5138 Say(at
, "The expression must not be polymorphic"_err_en_US
);
5139 } else if (auto shape
{ToArraySpec(
5140 GetFoldingContext(), evaluate::GetShape(*folded
))}) {
5141 // The type of the named constant is assumed from the expression.
5142 details
->set_type(*type
);
5143 details
->set_init(std::move(*folded
));
5144 details
->set_shape(std::move(*shape
));
5146 Say(at
, "The expression must have constant shape"_err_en_US
);
5149 Say(at
, "The expression must have a known type"_err_en_US
);
5152 Say(at
, "The expression must be a constant of known type"_err_en_US
);
5156 // standard-conforming PARAMETER statement (with parentheses)
5157 ApplyImplicitRules(symbol
);
5159 if (auto converted
{EvaluateNonPointerInitializer(
5160 symbol
, expr
, expr
.thing
.value().source
)}) {
5161 details
->set_init(std::move(*converted
));
5166 bool DeclarationVisitor::Pre(const parser::NamedConstant
&x
) {
5167 const parser::Name
&name
{x
.v
};
5168 if (!FindSymbol(name
)) {
5169 Say(name
, "Named constant '%s' not found"_err_en_US
);
5171 CheckUseError(name
);
5176 bool DeclarationVisitor::Pre(const parser::Enumerator
&enumerator
) {
5177 const parser::Name
&name
{std::get
<parser::NamedConstant
>(enumerator
.t
).v
};
5178 Symbol
*symbol
{FindInScope(name
)};
5179 if (symbol
&& !symbol
->has
<UnknownDetails
>()) {
5180 // Contrary to named constants appearing in a PARAMETER statement,
5181 // enumerator names should not have their type, dimension or any other
5182 // attributes defined before they are declared in the enumerator statement,
5183 // with the exception of accessibility.
5184 // This is not explicitly forbidden by the standard, but they are scalars
5185 // which type is left for the compiler to chose, so do not let users try to
5186 // tamper with that.
5187 SayAlreadyDeclared(name
, *symbol
);
5190 // Enumerators are treated as PARAMETER (section 7.6 paragraph (4))
5191 symbol
= &MakeSymbol(name
, Attrs
{Attr::PARAMETER
}, ObjectEntityDetails
{});
5192 symbol
->SetType(context().MakeNumericType(
5193 TypeCategory::Integer
, evaluate::CInteger::kind
));
5196 if (auto &init
{std::get
<std::optional
<parser::ScalarIntConstantExpr
>>(
5198 Walk(*init
); // Resolve names in expression before evaluation.
5199 if (auto value
{EvaluateInt64(context(), *init
)}) {
5200 // Cast all init expressions to C_INT so that they can then be
5201 // safely incremented (see 7.6 Note 2).
5202 enumerationState_
.value
= static_cast<int>(*value
);
5205 "Enumerator value could not be computed "
5206 "from the given expression"_err_en_US
);
5207 // Prevent resolution of next enumerators value
5208 enumerationState_
.value
= std::nullopt
;
5213 if (enumerationState_
.value
) {
5214 symbol
->get
<ObjectEntityDetails
>().set_init(SomeExpr
{
5215 evaluate::Expr
<evaluate::CInteger
>{*enumerationState_
.value
}});
5217 context().SetError(*symbol
);
5221 if (enumerationState_
.value
) {
5222 (*enumerationState_
.value
)++;
5227 void DeclarationVisitor::Post(const parser::EnumDef
&) {
5228 enumerationState_
= EnumeratorState
{};
5231 bool DeclarationVisitor::Pre(const parser::AccessSpec
&x
) {
5232 Attr attr
{AccessSpecToAttr(x
)};
5233 if (!NonDerivedTypeScope().IsModule()) { // C817
5234 Say(currStmtSource().value(),
5235 "%s attribute may only appear in the specification part of a module"_err_en_US
,
5236 EnumToString(attr
));
5242 bool DeclarationVisitor::Pre(const parser::AsynchronousStmt
&x
) {
5243 return HandleAttributeStmt(Attr::ASYNCHRONOUS
, x
.v
);
5245 bool DeclarationVisitor::Pre(const parser::ContiguousStmt
&x
) {
5246 return HandleAttributeStmt(Attr::CONTIGUOUS
, x
.v
);
5248 bool DeclarationVisitor::Pre(const parser::ExternalStmt
&x
) {
5249 HandleAttributeStmt(Attr::EXTERNAL
, x
.v
);
5250 for (const auto &name
: x
.v
) {
5251 auto *symbol
{FindSymbol(name
)};
5252 if (!ConvertToProcEntity(DEREF(symbol
), name
.source
)) {
5253 // Check if previous symbol is an interface.
5254 if (auto *details
{symbol
->detailsIf
<SubprogramDetails
>()}) {
5255 if (details
->isInterface()) {
5256 // Warn if interface previously declared.
5257 context().Warn(common::LanguageFeature::RedundantAttribute
,
5259 "EXTERNAL attribute was already specified on '%s'"_warn_en_US
,
5264 name
, *symbol
, "EXTERNAL attribute not allowed on '%s'"_err_en_US
);
5266 } else if (symbol
->attrs().test(Attr::INTRINSIC
)) { // C840
5268 "Symbol '%s' cannot have both INTRINSIC and EXTERNAL attributes"_err_en_US
,
5274 bool DeclarationVisitor::Pre(const parser::IntentStmt
&x
) {
5275 auto &intentSpec
{std::get
<parser::IntentSpec
>(x
.t
)};
5276 auto &names
{std::get
<std::list
<parser::Name
>>(x
.t
)};
5277 return CheckNotInBlock("INTENT") && // C1107
5278 HandleAttributeStmt(IntentSpecToAttr(intentSpec
), names
);
5280 bool DeclarationVisitor::Pre(const parser::IntrinsicStmt
&x
) {
5281 for (const auto &name
: x
.v
) {
5282 DeclareIntrinsic(name
);
5286 void DeclarationVisitor::DeclareIntrinsic(const parser::Name
&name
) {
5287 HandleAttributeStmt(Attr::INTRINSIC
, name
);
5288 if (!IsIntrinsic(name
.source
, std::nullopt
)) {
5289 Say(name
.source
, "'%s' is not a known intrinsic procedure"_err_en_US
);
5291 auto &symbol
{DEREF(FindSymbol(name
))};
5292 if (symbol
.has
<GenericDetails
>()) {
5293 // Generic interface is extending intrinsic; ok
5294 } else if (!ConvertToProcEntity(symbol
, name
.source
)) {
5296 name
, symbol
, "INTRINSIC attribute not allowed on '%s'"_err_en_US
);
5297 } else if (symbol
.attrs().test(Attr::EXTERNAL
)) { // C840
5299 "Symbol '%s' cannot have both EXTERNAL and INTRINSIC attributes"_err_en_US
,
5302 if (symbol
.GetType()) {
5303 // These warnings are worded so that they should make sense in either
5305 if (auto *msg
{context().Warn(
5306 common::UsageWarning::IgnoredIntrinsicFunctionType
, symbol
.name(),
5307 "Explicit type declaration ignored for intrinsic function '%s'"_warn_en_US
,
5309 msg
->Attach(name
.source
,
5310 "INTRINSIC statement for explicitly-typed '%s'"_en_US
, name
.source
);
5313 if (!symbol
.test(Symbol::Flag::Function
) &&
5314 !symbol
.test(Symbol::Flag::Subroutine
)) {
5315 if (context().intrinsics().IsIntrinsicFunction(name
.source
.ToString())) {
5316 symbol
.set(Symbol::Flag::Function
);
5317 } else if (context().intrinsics().IsIntrinsicSubroutine(
5318 name
.source
.ToString())) {
5319 symbol
.set(Symbol::Flag::Subroutine
);
5324 bool DeclarationVisitor::Pre(const parser::OptionalStmt
&x
) {
5325 return CheckNotInBlock("OPTIONAL") && // C1107
5326 HandleAttributeStmt(Attr::OPTIONAL
, x
.v
);
5328 bool DeclarationVisitor::Pre(const parser::ProtectedStmt
&x
) {
5329 return HandleAttributeStmt(Attr::PROTECTED
, x
.v
);
5331 bool DeclarationVisitor::Pre(const parser::ValueStmt
&x
) {
5332 return CheckNotInBlock("VALUE") && // C1107
5333 HandleAttributeStmt(Attr::VALUE
, x
.v
);
5335 bool DeclarationVisitor::Pre(const parser::VolatileStmt
&x
) {
5336 return HandleAttributeStmt(Attr::VOLATILE
, x
.v
);
5338 bool DeclarationVisitor::Pre(const parser::CUDAAttributesStmt
&x
) {
5339 auto attr
{std::get
<common::CUDADataAttr
>(x
.t
)};
5340 for (const auto &name
: std::get
<std::list
<parser::Name
>>(x
.t
)) {
5341 auto *symbol
{FindInScope(name
)};
5342 if (symbol
&& symbol
->has
<UseDetails
>()) {
5343 Say(currStmtSource().value(),
5344 "Cannot apply CUDA data attribute to use-associated '%s'"_err_en_US
,
5348 symbol
= &MakeSymbol(name
, ObjectEntityDetails
{});
5350 SetCUDADataAttr(name
.source
, *symbol
, attr
);
5355 // Handle a statement that sets an attribute on a list of names.
5356 bool DeclarationVisitor::HandleAttributeStmt(
5357 Attr attr
, const std::list
<parser::Name
> &names
) {
5358 for (const auto &name
: names
) {
5359 HandleAttributeStmt(attr
, name
);
5363 Symbol
&DeclarationVisitor::HandleAttributeStmt(
5364 Attr attr
, const parser::Name
&name
) {
5365 auto *symbol
{FindInScope(name
)};
5366 if (attr
== Attr::ASYNCHRONOUS
|| attr
== Attr::VOLATILE
) {
5367 // these can be set on a symbol that is host-assoc or use-assoc
5369 (currScope().kind() == Scope::Kind::Subprogram
||
5370 currScope().kind() == Scope::Kind::BlockConstruct
)) {
5371 if (auto *hostSymbol
{FindSymbol(name
)}) {
5372 symbol
= &MakeHostAssocSymbol(name
, *hostSymbol
);
5375 } else if (symbol
&& symbol
->has
<UseDetails
>()) {
5376 if (symbol
->GetUltimate().attrs().test(attr
)) {
5377 context().Warn(common::LanguageFeature::RedundantAttribute
,
5378 currStmtSource().value(),
5379 "Use-associated '%s' already has '%s' attribute"_warn_en_US
,
5380 name
.source
, EnumToString(attr
));
5382 Say(currStmtSource().value(),
5383 "Cannot change %s attribute on use-associated '%s'"_err_en_US
,
5384 EnumToString(attr
), name
.source
);
5389 symbol
= &MakeSymbol(name
, EntityDetails
{});
5391 if (CheckDuplicatedAttr(name
.source
, *symbol
, attr
)) {
5392 HandleSaveName(name
.source
, Attrs
{attr
});
5393 SetExplicitAttr(*symbol
, attr
);
5398 bool DeclarationVisitor::CheckNotInBlock(const char *stmt
) {
5399 if (currScope().kind() == Scope::Kind::BlockConstruct
) {
5400 Say(MessageFormattedText
{
5401 "%s statement is not allowed in a BLOCK construct"_err_en_US
, stmt
});
5408 void DeclarationVisitor::Post(const parser::ObjectDecl
&x
) {
5409 CHECK(objectDeclAttr_
);
5410 const auto &name
{std::get
<parser::ObjectName
>(x
.t
)};
5411 DeclareObjectEntity(name
, Attrs
{*objectDeclAttr_
});
5414 // Declare an entity not yet known to be an object or proc.
5415 Symbol
&DeclarationVisitor::DeclareUnknownEntity(
5416 const parser::Name
&name
, Attrs attrs
) {
5417 if (!arraySpec().empty() || !coarraySpec().empty()) {
5418 return DeclareObjectEntity(name
, attrs
);
5420 Symbol
&symbol
{DeclareEntity
<EntityDetails
>(name
, attrs
)};
5421 if (auto *type
{GetDeclTypeSpec()}) {
5422 SetType(name
, *type
);
5424 charInfo_
.length
.reset();
5425 if (symbol
.attrs().test(Attr::EXTERNAL
)) {
5426 ConvertToProcEntity(symbol
);
5427 } else if (symbol
.attrs().HasAny(Attrs
{Attr::ALLOCATABLE
,
5428 Attr::ASYNCHRONOUS
, Attr::CONTIGUOUS
, Attr::PARAMETER
,
5429 Attr::SAVE
, Attr::TARGET
, Attr::VALUE
, Attr::VOLATILE
})) {
5430 ConvertToObjectEntity(symbol
);
5432 if (attrs
.test(Attr::BIND_C
)) {
5433 SetBindNameOn(symbol
);
5439 bool DeclarationVisitor::HasCycle(
5440 const Symbol
&procSymbol
, const Symbol
*interface
) {
5441 SourceOrderedSymbolSet procsInCycle
;
5442 procsInCycle
.insert(procSymbol
);
5444 if (procsInCycle
.count(*interface
) > 0) {
5445 for (const auto &procInCycle
: procsInCycle
) {
5446 Say(procInCycle
->name(),
5447 "The interface for procedure '%s' is recursively defined"_err_en_US
,
5448 procInCycle
->name());
5449 context().SetError(*procInCycle
);
5452 } else if (const auto *procDetails
{
5453 interface
->detailsIf
<ProcEntityDetails
>()}) {
5454 procsInCycle
.insert(*interface
);
5455 interface
= procDetails
->procInterface();
5463 Symbol
&DeclarationVisitor::DeclareProcEntity(
5464 const parser::Name
&name
, Attrs attrs
, const Symbol
*interface
) {
5465 Symbol
*proc
{nullptr};
5466 if (auto *extant
{FindInScope(name
)}) {
5467 if (auto *d
{extant
->detailsIf
<GenericDetails
>()}; d
&& !d
->derivedType()) {
5468 // procedure pointer with same name as a generic
5469 if (auto *specific
{d
->specific()}) {
5470 SayAlreadyDeclared(name
, *specific
);
5472 // Create the ProcEntityDetails symbol in the scope as the "specific()"
5473 // symbol behind an existing GenericDetails symbol of the same name.
5474 proc
= &Resolve(name
,
5475 currScope().MakeSymbol(name
.source
, attrs
, ProcEntityDetails
{}));
5476 d
->set_specific(*proc
);
5480 Symbol
&symbol
{proc
? *proc
: DeclareEntity
<ProcEntityDetails
>(name
, attrs
)};
5481 if (auto *details
{symbol
.detailsIf
<ProcEntityDetails
>()}) {
5482 if (context().HasError(symbol
)) {
5483 } else if (HasCycle(symbol
, interface
)) {
5485 } else if (interface
&& (details
->procInterface() || details
->type())) {
5486 SayWithDecl(name
, symbol
,
5487 "The interface for procedure '%s' has already been declared"_err_en_US
);
5488 context().SetError(symbol
);
5489 } else if (interface
) {
5490 details
->set_procInterfaces(
5491 *interface
, BypassGeneric(interface
->GetUltimate()));
5492 if (interface
->test(Symbol::Flag::Function
)) {
5493 symbol
.set(Symbol::Flag::Function
);
5494 } else if (interface
->test(Symbol::Flag::Subroutine
)) {
5495 symbol
.set(Symbol::Flag::Subroutine
);
5497 } else if (auto *type
{GetDeclTypeSpec()}) {
5498 SetType(name
, *type
);
5499 symbol
.set(Symbol::Flag::Function
);
5501 SetBindNameOn(symbol
);
5502 SetPassNameOn(symbol
);
5507 Symbol
&DeclarationVisitor::DeclareObjectEntity(
5508 const parser::Name
&name
, Attrs attrs
) {
5509 Symbol
&symbol
{DeclareEntity
<ObjectEntityDetails
>(name
, attrs
)};
5510 if (auto *details
{symbol
.detailsIf
<ObjectEntityDetails
>()}) {
5511 if (auto *type
{GetDeclTypeSpec()}) {
5512 SetType(name
, *type
);
5514 if (!arraySpec().empty()) {
5515 if (details
->IsArray()) {
5516 if (!context().HasError(symbol
)) {
5518 "The dimensions of '%s' have already been declared"_err_en_US
);
5519 context().SetError(symbol
);
5521 } else if (MustBeScalar(symbol
)) {
5522 context().Warn(common::UsageWarning::PreviousScalarUse
, name
.source
,
5523 "'%s' appeared earlier as a scalar actual argument to a specification function"_warn_en_US
,
5525 } else if (details
->init() || symbol
.test(Symbol::Flag::InDataStmt
)) {
5526 Say(name
, "'%s' was initialized earlier as a scalar"_err_en_US
);
5528 details
->set_shape(arraySpec());
5531 if (!coarraySpec().empty()) {
5532 if (details
->IsCoarray()) {
5533 if (!context().HasError(symbol
)) {
5535 "The codimensions of '%s' have already been declared"_err_en_US
);
5536 context().SetError(symbol
);
5539 details
->set_coshape(coarraySpec());
5542 SetBindNameOn(symbol
);
5546 charInfo_
.length
.reset();
5550 void DeclarationVisitor::Post(const parser::IntegerTypeSpec
&x
) {
5551 if (!isVectorType_
) {
5552 SetDeclTypeSpec(MakeNumericType(TypeCategory::Integer
, x
.v
));
5555 void DeclarationVisitor::Post(const parser::UnsignedTypeSpec
&x
) {
5556 if (!isVectorType_
) {
5557 if (!context().IsEnabled(common::LanguageFeature::Unsigned
) &&
5558 !context().AnyFatalError()) {
5559 context().Say("-funsigned is required to enable UNSIGNED type"_err_en_US
);
5561 SetDeclTypeSpec(MakeNumericType(TypeCategory::Unsigned
, x
.v
));
5564 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Real
&x
) {
5565 if (!isVectorType_
) {
5566 SetDeclTypeSpec(MakeNumericType(TypeCategory::Real
, x
.kind
));
5569 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Complex
&x
) {
5570 SetDeclTypeSpec(MakeNumericType(TypeCategory::Complex
, x
.kind
));
5572 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Logical
&x
) {
5573 SetDeclTypeSpec(MakeLogicalType(x
.kind
));
5575 void DeclarationVisitor::Post(const parser::IntrinsicTypeSpec::Character
&) {
5576 if (!charInfo_
.length
) {
5577 charInfo_
.length
= ParamValue
{1, common::TypeParamAttr::Len
};
5579 if (!charInfo_
.kind
) {
5581 KindExpr
{context().GetDefaultKind(TypeCategory::Character
)};
5583 SetDeclTypeSpec(currScope().MakeCharacterType(
5584 std::move(*charInfo_
.length
), std::move(*charInfo_
.kind
)));
5587 void DeclarationVisitor::Post(const parser::CharSelector::LengthAndKind
&x
) {
5588 charInfo_
.kind
= EvaluateSubscriptIntExpr(x
.kind
);
5589 std::optional
<std::int64_t> intKind
{ToInt64(charInfo_
.kind
)};
5591 !context().targetCharacteristics().IsTypeEnabled(
5592 TypeCategory::Character
, *intKind
)) { // C715, C719
5593 Say(currStmtSource().value(),
5594 "KIND value (%jd) not valid for CHARACTER"_err_en_US
, *intKind
);
5595 charInfo_
.kind
= std::nullopt
; // prevent further errors
5598 charInfo_
.length
= GetParamValue(*x
.length
, common::TypeParamAttr::Len
);
5601 void DeclarationVisitor::Post(const parser::CharLength
&x
) {
5602 if (const auto *length
{std::get_if
<std::uint64_t>(&x
.u
)}) {
5603 charInfo_
.length
= ParamValue
{
5604 static_cast<ConstantSubscript
>(*length
), common::TypeParamAttr::Len
};
5606 charInfo_
.length
= GetParamValue(
5607 std::get
<parser::TypeParamValue
>(x
.u
), common::TypeParamAttr::Len
);
5610 void DeclarationVisitor::Post(const parser::LengthSelector
&x
) {
5611 if (const auto *param
{std::get_if
<parser::TypeParamValue
>(&x
.u
)}) {
5612 charInfo_
.length
= GetParamValue(*param
, common::TypeParamAttr::Len
);
5616 bool DeclarationVisitor::Pre(const parser::KindParam
&x
) {
5617 if (const auto *kind
{std::get_if
<
5618 parser::Scalar
<parser::Integer
<parser::Constant
<parser::Name
>>>>(
5620 const parser::Name
&name
{kind
->thing
.thing
.thing
};
5621 if (!FindSymbol(name
)) {
5622 Say(name
, "Parameter '%s' not found"_err_en_US
);
5628 int DeclarationVisitor::GetVectorElementKind(
5629 TypeCategory category
, const std::optional
<parser::KindSelector
> &kind
) {
5630 KindExpr value
{GetKindParamExpr(category
, kind
)};
5631 if (auto known
{evaluate::ToInt64(value
)}) {
5632 return static_cast<int>(*known
);
5634 common::die("Vector element kind must be known at compile-time");
5637 bool DeclarationVisitor::Pre(const parser::VectorTypeSpec
&) {
5638 // PowerPC vector types are allowed only on Power architectures.
5639 if (!currScope().context().targetCharacteristics().isPPC()) {
5640 Say(currStmtSource().value(),
5641 "Vector type is only supported for PowerPC"_err_en_US
);
5642 isVectorType_
= false;
5645 isVectorType_
= true;
5648 // Create semantic::DerivedTypeSpec for Vector types here.
5649 void DeclarationVisitor::Post(const parser::VectorTypeSpec
&x
) {
5650 llvm::StringRef typeName
;
5651 llvm::SmallVector
<ParamValue
> typeParams
;
5652 DerivedTypeSpec::Category vectorCategory
;
5654 isVectorType_
= false;
5657 [&](const parser::IntrinsicVectorTypeSpec
&y
) {
5658 vectorCategory
= DerivedTypeSpec::Category::IntrinsicVector
;
5659 int vecElemKind
= 0;
5660 typeName
= "__builtin_ppc_intrinsic_vector";
5663 [&](const parser::IntegerTypeSpec
&z
) {
5664 vecElemKind
= GetVectorElementKind(
5665 TypeCategory::Integer
, std::move(z
.v
));
5666 typeParams
.push_back(ParamValue(
5667 static_cast<common::ConstantSubscript
>(
5668 common::VectorElementCategory::Integer
),
5669 common::TypeParamAttr::Kind
));
5671 [&](const parser::IntrinsicTypeSpec::Real
&z
) {
5672 vecElemKind
= GetVectorElementKind(
5673 TypeCategory::Real
, std::move(z
.kind
));
5674 typeParams
.push_back(
5675 ParamValue(static_cast<common::ConstantSubscript
>(
5676 common::VectorElementCategory::Real
),
5677 common::TypeParamAttr::Kind
));
5679 [&](const parser::UnsignedTypeSpec
&z
) {
5680 vecElemKind
= GetVectorElementKind(
5681 TypeCategory::Integer
, std::move(z
.v
));
5682 typeParams
.push_back(ParamValue(
5683 static_cast<common::ConstantSubscript
>(
5684 common::VectorElementCategory::Unsigned
),
5685 common::TypeParamAttr::Kind
));
5689 typeParams
.push_back(
5690 ParamValue(static_cast<common::ConstantSubscript
>(vecElemKind
),
5691 common::TypeParamAttr::Kind
));
5693 [&](const parser::VectorTypeSpec::PairVectorTypeSpec
&y
) {
5694 vectorCategory
= DerivedTypeSpec::Category::PairVector
;
5695 typeName
= "__builtin_ppc_pair_vector";
5697 [&](const parser::VectorTypeSpec::QuadVectorTypeSpec
&y
) {
5698 vectorCategory
= DerivedTypeSpec::Category::QuadVector
;
5699 typeName
= "__builtin_ppc_quad_vector";
5704 auto ppcBuiltinTypesScope
= currScope().context().GetPPCBuiltinTypesScope();
5705 if (!ppcBuiltinTypesScope
) {
5706 common::die("INTERNAL: The __ppc_types module was not found ");
5709 auto iter
{ppcBuiltinTypesScope
->find(
5710 semantics::SourceName
{typeName
.data(), typeName
.size()})};
5711 if (iter
== ppcBuiltinTypesScope
->cend()) {
5712 common::die("INTERNAL: The __ppc_types module does not define "
5717 const semantics::Symbol
&typeSymbol
{*iter
->second
};
5718 DerivedTypeSpec vectorDerivedType
{typeName
.data(), typeSymbol
};
5719 vectorDerivedType
.set_category(vectorCategory
);
5720 if (typeParams
.size()) {
5721 vectorDerivedType
.AddRawParamValue(nullptr, std::move(typeParams
[0]));
5722 vectorDerivedType
.AddRawParamValue(nullptr, std::move(typeParams
[1]));
5723 vectorDerivedType
.CookParameters(GetFoldingContext());
5726 if (const DeclTypeSpec
*
5727 extant
{ppcBuiltinTypesScope
->FindInstantiatedDerivedType(
5728 vectorDerivedType
, DeclTypeSpec::Category::TypeDerived
)}) {
5729 // This derived type and parameter expressions (if any) are already present
5730 // in the __ppc_intrinsics scope.
5731 SetDeclTypeSpec(*extant
);
5733 DeclTypeSpec
&type
{ppcBuiltinTypesScope
->MakeDerivedType(
5734 DeclTypeSpec::Category::TypeDerived
, std::move(vectorDerivedType
))};
5735 DerivedTypeSpec
&derived
{type
.derivedTypeSpec()};
5737 GetFoldingContext().messages().SetLocation(currStmtSource().value())};
5738 derived
.Instantiate(*ppcBuiltinTypesScope
);
5739 SetDeclTypeSpec(type
);
5743 bool DeclarationVisitor::Pre(const parser::DeclarationTypeSpec::Type
&) {
5744 CHECK(GetDeclTypeSpecCategory() == DeclTypeSpec::Category::TypeDerived
);
5748 void DeclarationVisitor::Post(const parser::DeclarationTypeSpec::Type
&type
) {
5749 const parser::Name
&derivedName
{std::get
<parser::Name
>(type
.derived
.t
)};
5750 if (const Symbol
* derivedSymbol
{derivedName
.symbol
}) {
5751 CheckForAbstractType(*derivedSymbol
); // C706
5755 bool DeclarationVisitor::Pre(const parser::DeclarationTypeSpec::Class
&) {
5756 SetDeclTypeSpecCategory(DeclTypeSpec::Category::ClassDerived
);
5760 void DeclarationVisitor::Post(
5761 const parser::DeclarationTypeSpec::Class
&parsedClass
) {
5762 const auto &typeName
{std::get
<parser::Name
>(parsedClass
.derived
.t
)};
5763 if (auto spec
{ResolveDerivedType(typeName
)};
5764 spec
&& !IsExtensibleType(&*spec
)) { // C705
5765 SayWithDecl(typeName
, *typeName
.symbol
,
5766 "Non-extensible derived type '%s' may not be used with CLASS"
5767 " keyword"_err_en_US
);
5771 void DeclarationVisitor::Post(const parser::DerivedTypeSpec
&x
) {
5772 const auto &typeName
{std::get
<parser::Name
>(x
.t
)};
5773 auto spec
{ResolveDerivedType(typeName
)};
5777 bool seenAnyName
{false};
5778 for (const auto &typeParamSpec
:
5779 std::get
<std::list
<parser::TypeParamSpec
>>(x
.t
)) {
5780 const auto &optKeyword
{
5781 std::get
<std::optional
<parser::Keyword
>>(typeParamSpec
.t
)};
5782 std::optional
<SourceName
> name
;
5785 name
= optKeyword
->v
.source
;
5786 } else if (seenAnyName
) {
5787 Say(typeName
.source
, "Type parameter value must have a name"_err_en_US
);
5790 const auto &value
{std::get
<parser::TypeParamValue
>(typeParamSpec
.t
)};
5791 // The expressions in a derived type specifier whose values define
5792 // non-defaulted type parameters are evaluated (folded) in the enclosing
5793 // scope. The KIND/LEN distinction is resolved later in
5794 // DerivedTypeSpec::CookParameters().
5795 ParamValue param
{GetParamValue(value
, common::TypeParamAttr::Kind
)};
5796 if (!param
.isExplicit() || param
.GetExplicit()) {
5797 spec
->AddRawParamValue(
5798 common::GetPtrFromOptional(optKeyword
), std::move(param
));
5801 // The DerivedTypeSpec *spec is used initially as a search key.
5802 // If it turns out to have the same name and actual parameter
5803 // value expressions as another DerivedTypeSpec in the current
5804 // scope does, then we'll use that extant spec; otherwise, when this
5805 // spec is distinct from all derived types previously instantiated
5806 // in the current scope, this spec will be moved into that collection.
5807 const auto &dtDetails
{spec
->typeSymbol().get
<DerivedTypeDetails
>()};
5808 auto category
{GetDeclTypeSpecCategory()};
5809 if (dtDetails
.isForwardReferenced()) {
5810 DeclTypeSpec
&type
{currScope().MakeDerivedType(category
, std::move(*spec
))};
5811 SetDeclTypeSpec(type
);
5814 // Normalize parameters to produce a better search key.
5815 spec
->CookParameters(GetFoldingContext());
5816 if (!spec
->MightBeParameterized()) {
5817 spec
->EvaluateParameters(context());
5819 if (const DeclTypeSpec
*
5820 extant
{currScope().FindInstantiatedDerivedType(*spec
, category
)}) {
5821 // This derived type and parameter expressions (if any) are already present
5823 SetDeclTypeSpec(*extant
);
5825 DeclTypeSpec
&type
{currScope().MakeDerivedType(category
, std::move(*spec
))};
5826 DerivedTypeSpec
&derived
{type
.derivedTypeSpec()};
5827 if (derived
.MightBeParameterized() &&
5828 currScope().IsParameterizedDerivedType()) {
5829 // Defer instantiation; use the derived type's definition's scope.
5830 derived
.set_scope(DEREF(spec
->typeSymbol().scope()));
5831 } else if (&currScope() == spec
->typeSymbol().scope()) {
5832 // Direct recursive use of a type in the definition of one of its
5833 // components: defer instantiation
5836 GetFoldingContext().messages().SetLocation(currStmtSource().value())};
5837 derived
.Instantiate(currScope());
5839 SetDeclTypeSpec(type
);
5841 // Capture the DerivedTypeSpec in the parse tree for use in building
5842 // structure constructor expressions.
5843 x
.derivedTypeSpec
= &GetDeclTypeSpec()->derivedTypeSpec();
5846 void DeclarationVisitor::Post(const parser::DeclarationTypeSpec::Record
&rec
) {
5847 const auto &typeName
{rec
.v
};
5848 if (auto spec
{ResolveDerivedType(typeName
)}) {
5849 spec
->CookParameters(GetFoldingContext());
5850 spec
->EvaluateParameters(context());
5851 if (const DeclTypeSpec
*
5852 extant
{currScope().FindInstantiatedDerivedType(
5853 *spec
, DeclTypeSpec::TypeDerived
)}) {
5854 SetDeclTypeSpec(*extant
);
5856 Say(typeName
.source
, "%s is not a known STRUCTURE"_err_en_US
,
5862 // The descendents of DerivedTypeDef in the parse tree are visited directly
5863 // in this Pre() routine so that recursive use of the derived type can be
5864 // supported in the components.
5865 bool DeclarationVisitor::Pre(const parser::DerivedTypeDef
&x
) {
5866 auto &stmt
{std::get
<parser::Statement
<parser::DerivedTypeStmt
>>(x
.t
)};
5868 Walk(std::get
<std::list
<parser::Statement
<parser::TypeParamDefStmt
>>>(x
.t
));
5869 auto &scope
{currScope()};
5870 CHECK(scope
.symbol());
5871 CHECK(scope
.symbol()->scope() == &scope
);
5872 auto &details
{scope
.symbol()->get
<DerivedTypeDetails
>()};
5873 for (auto ¶mName
: std::get
<std::list
<parser::Name
>>(stmt
.statement
.t
)) {
5874 if (auto *symbol
{FindInScope(scope
, paramName
)}) {
5875 if (auto *details
{symbol
->detailsIf
<TypeParamDetails
>()}) {
5876 if (!details
->attr()) {
5878 "No definition found for type parameter '%s'"_err_en_US
); // C742
5883 Walk(std::get
<std::list
<parser::Statement
<parser::PrivateOrSequence
>>>(x
.t
));
5884 const auto &componentDefs
{
5885 std::get
<std::list
<parser::Statement
<parser::ComponentDefStmt
>>>(x
.t
)};
5886 Walk(componentDefs
);
5887 if (derivedTypeInfo_
.sequence
) {
5888 details
.set_sequence(true);
5889 if (componentDefs
.empty()) {
5890 // F'2023 C745 - not enforced by any compiler
5891 context().Warn(common::LanguageFeature::EmptySequenceType
, stmt
.source
,
5892 "A sequence type should have at least one component"_warn_en_US
);
5894 if (!details
.paramDeclOrder().empty()) { // C740
5896 "A sequence type may not have type parameters"_err_en_US
);
5898 if (derivedTypeInfo_
.extends
) { // C735
5900 "A sequence type may not have the EXTENDS attribute"_err_en_US
);
5903 Walk(std::get
<std::optional
<parser::TypeBoundProcedurePart
>>(x
.t
));
5904 Walk(std::get
<parser::Statement
<parser::EndTypeStmt
>>(x
.t
));
5905 details
.set_isForwardReferenced(false);
5906 derivedTypeInfo_
= {};
5911 bool DeclarationVisitor::Pre(const parser::DerivedTypeStmt
&) {
5912 return BeginAttrs();
5914 void DeclarationVisitor::Post(const parser::DerivedTypeStmt
&x
) {
5915 auto &name
{std::get
<parser::Name
>(x
.t
)};
5916 // Resolve the EXTENDS() clause before creating the derived
5917 // type's symbol to foil attempts to recursively extend a type.
5918 auto *extendsName
{derivedTypeInfo_
.extends
};
5919 std::optional
<DerivedTypeSpec
> extendsType
{
5920 ResolveExtendsType(name
, extendsName
)};
5921 DerivedTypeDetails derivedTypeDetails
;
5922 // Catch any premature structure constructors within the definition
5923 derivedTypeDetails
.set_isForwardReferenced(true);
5924 auto &symbol
{MakeSymbol(name
, GetAttrs(), std::move(derivedTypeDetails
))};
5925 symbol
.ReplaceName(name
.source
);
5926 derivedTypeInfo_
.type
= &symbol
;
5927 PushScope(Scope::Kind::DerivedType
, &symbol
);
5929 // Declare the "parent component"; private if the type is.
5930 // Any symbol stored in the EXTENDS() clause is temporarily
5931 // hidden so that a new symbol can be created for the parent
5932 // component without producing spurious errors about already
5934 const Symbol
&extendsSymbol
{extendsType
->typeSymbol()};
5935 auto restorer
{common::ScopedSet(extendsName
->symbol
, nullptr)};
5936 if (OkToAddComponent(*extendsName
, &extendsSymbol
)) {
5937 auto &comp
{DeclareEntity
<ObjectEntityDetails
>(*extendsName
, Attrs
{})};
5939 Attr::PRIVATE
, extendsSymbol
.attrs().test(Attr::PRIVATE
));
5940 comp
.implicitAttrs().set(
5941 Attr::PRIVATE
, extendsSymbol
.implicitAttrs().test(Attr::PRIVATE
));
5942 comp
.set(Symbol::Flag::ParentComp
);
5943 DeclTypeSpec
&type
{currScope().MakeDerivedType(
5944 DeclTypeSpec::TypeDerived
, std::move(*extendsType
))};
5945 type
.derivedTypeSpec().set_scope(DEREF(extendsSymbol
.scope()));
5947 DerivedTypeDetails
&details
{symbol
.get
<DerivedTypeDetails
>()};
5948 details
.add_component(comp
);
5951 // Create symbols now for type parameters so that they shadow names
5952 // from the enclosing specification part.
5953 if (auto *details
{symbol
.detailsIf
<DerivedTypeDetails
>()}) {
5954 for (const auto &name
: std::get
<std::list
<parser::Name
>>(x
.t
)) {
5955 if (Symbol
* symbol
{MakeTypeSymbol(name
, TypeParamDetails
{})}) {
5956 details
->add_paramNameOrder(*symbol
);
5963 void DeclarationVisitor::Post(const parser::TypeParamDefStmt
&x
) {
5964 auto *type
{GetDeclTypeSpec()};
5965 DerivedTypeDetails
*derivedDetails
{nullptr};
5966 if (Symbol
* dtSym
{currScope().symbol()}) {
5967 derivedDetails
= dtSym
->detailsIf
<DerivedTypeDetails
>();
5969 auto attr
{std::get
<common::TypeParamAttr
>(x
.t
)};
5970 for (auto &decl
: std::get
<std::list
<parser::TypeParamDecl
>>(x
.t
)) {
5971 auto &name
{std::get
<parser::Name
>(decl
.t
)};
5972 if (Symbol
* symbol
{FindInScope(currScope(), name
)}) {
5973 if (auto *paramDetails
{symbol
->detailsIf
<TypeParamDetails
>()}) {
5974 if (!paramDetails
->attr()) {
5975 paramDetails
->set_attr(attr
);
5976 SetType(name
, *type
);
5977 if (auto &init
{std::get
<std::optional
<parser::ScalarIntConstantExpr
>>(
5979 if (auto maybeExpr
{AnalyzeExpr(context(), *init
)}) {
5980 if (auto *intExpr
{std::get_if
<SomeIntExpr
>(&maybeExpr
->u
)}) {
5981 paramDetails
->set_init(std::move(*intExpr
));
5985 if (derivedDetails
) {
5986 derivedDetails
->add_paramDeclOrder(*symbol
);
5990 "Type parameter '%s' was already declared in this derived type"_err_en_US
);
5994 Say(name
, "'%s' is not a parameter of this derived type"_err_en_US
);
5999 bool DeclarationVisitor::Pre(const parser::TypeAttrSpec::Extends
&x
) {
6000 if (derivedTypeInfo_
.extends
) {
6001 Say(currStmtSource().value(),
6002 "Attribute 'EXTENDS' cannot be used more than once"_err_en_US
);
6004 derivedTypeInfo_
.extends
= &x
.v
;
6009 bool DeclarationVisitor::Pre(const parser::PrivateStmt
&) {
6010 if (!currScope().parent().IsModule()) {
6011 Say("PRIVATE is only allowed in a derived type that is"
6012 " in a module"_err_en_US
); // C766
6013 } else if (derivedTypeInfo_
.sawContains
) {
6014 derivedTypeInfo_
.privateBindings
= true;
6015 } else if (!derivedTypeInfo_
.privateComps
) {
6016 derivedTypeInfo_
.privateComps
= true;
6018 context().Warn(common::LanguageFeature::RedundantAttribute
,
6019 "PRIVATE should not appear more than once in derived type components"_warn_en_US
);
6023 bool DeclarationVisitor::Pre(const parser::SequenceStmt
&) {
6024 if (derivedTypeInfo_
.sequence
) { // C738
6025 context().Warn(common::LanguageFeature::RedundantAttribute
,
6026 "SEQUENCE should not appear more than once in derived type components"_warn_en_US
);
6028 derivedTypeInfo_
.sequence
= true;
6031 void DeclarationVisitor::Post(const parser::ComponentDecl
&x
) {
6032 const auto &name
{std::get
<parser::Name
>(x
.t
)};
6033 auto attrs
{GetAttrs()};
6034 if (derivedTypeInfo_
.privateComps
&&
6035 !attrs
.HasAny({Attr::PUBLIC
, Attr::PRIVATE
})) {
6036 attrs
.set(Attr::PRIVATE
);
6038 if (const auto *declType
{GetDeclTypeSpec()}) {
6039 if (const auto *derived
{declType
->AsDerived()}) {
6040 if (!attrs
.HasAny({Attr::POINTER
, Attr::ALLOCATABLE
})) {
6041 if (derivedTypeInfo_
.type
== &derived
->typeSymbol()) { // C744
6042 Say("Recursive use of the derived type requires "
6043 "POINTER or ALLOCATABLE"_err_en_US
);
6046 // TODO: This would be more appropriate in CheckDerivedType()
6047 if (auto it
{FindCoarrayUltimateComponent(*derived
)}) { // C748
6048 std::string ultimateName
{it
.BuildResultDesignatorName()};
6049 // Strip off the leading "%"
6050 if (ultimateName
.length() > 1) {
6051 ultimateName
.erase(0, 1);
6052 if (attrs
.HasAny({Attr::POINTER
, Attr::ALLOCATABLE
})) {
6053 evaluate::AttachDeclaration(
6055 "A component with a POINTER or ALLOCATABLE attribute may "
6057 "be of a type with a coarray ultimate component (named "
6060 derived
->typeSymbol());
6062 if (!arraySpec().empty() || !coarraySpec().empty()) {
6063 evaluate::AttachDeclaration(
6065 "An array or coarray component may not be of a type with a "
6066 "coarray ultimate component (named '%s')"_err_en_US
,
6068 derived
->typeSymbol());
6074 if (OkToAddComponent(name
)) {
6075 auto &symbol
{DeclareObjectEntity(name
, attrs
)};
6076 SetCUDADataAttr(name
.source
, symbol
, cudaDataAttr());
6077 if (symbol
.has
<ObjectEntityDetails
>()) {
6078 if (auto &init
{std::get
<std::optional
<parser::Initialization
>>(x
.t
)}) {
6079 Initialization(name
, *init
, true);
6082 currScope().symbol()->get
<DerivedTypeDetails
>().add_component(symbol
);
6087 void DeclarationVisitor::Post(const parser::FillDecl
&x
) {
6088 // Replace "%FILL" with a distinct generated name
6089 const auto &name
{std::get
<parser::Name
>(x
.t
)};
6090 const_cast<SourceName
&>(name
.source
) = context().GetTempName(currScope());
6091 if (OkToAddComponent(name
)) {
6092 auto &symbol
{DeclareObjectEntity(name
, GetAttrs())};
6093 currScope().symbol()->get
<DerivedTypeDetails
>().add_component(symbol
);
6097 bool DeclarationVisitor::Pre(const parser::ProcedureDeclarationStmt
&x
) {
6098 CHECK(!interfaceName_
);
6099 const auto &procAttrSpec
{std::get
<std::list
<parser::ProcAttrSpec
>>(x
.t
)};
6100 for (const parser::ProcAttrSpec
&procAttr
: procAttrSpec
) {
6101 if (auto *bindC
{std::get_if
<parser::LanguageBindingSpec
>(&procAttr
.u
)}) {
6102 if (std::get
<std::optional
<parser::ScalarDefaultCharConstantExpr
>>(
6105 if (std::get
<std::list
<parser::ProcDecl
>>(x
.t
).size() > 1) {
6106 Say(context().location().value(),
6107 "A procedure declaration statement with a binding name may not declare multiple procedures"_err_en_US
);
6115 void DeclarationVisitor::Post(const parser::ProcedureDeclarationStmt
&) {
6116 interfaceName_
= nullptr;
6119 bool DeclarationVisitor::Pre(const parser::DataComponentDefStmt
&x
) {
6120 // Overrides parse tree traversal so as to handle attributes first,
6121 // so POINTER & ALLOCATABLE enable forward references to derived types.
6122 Walk(std::get
<std::list
<parser::ComponentAttrSpec
>>(x
.t
));
6123 set_allowForwardReferenceToDerivedType(
6124 GetAttrs().HasAny({Attr::POINTER
, Attr::ALLOCATABLE
}));
6125 Walk(std::get
<parser::DeclarationTypeSpec
>(x
.t
));
6126 set_allowForwardReferenceToDerivedType(false);
6127 if (derivedTypeInfo_
.sequence
) { // C740
6128 if (const auto *declType
{GetDeclTypeSpec()}) {
6129 if (!declType
->AsIntrinsic() && !declType
->IsSequenceType() &&
6131 if (GetAttrs().test(Attr::POINTER
) &&
6132 context().IsEnabled(common::LanguageFeature::PointerInSeqType
)) {
6133 context().Warn(common::LanguageFeature::PointerInSeqType
,
6134 "A sequence type data component that is a pointer to a non-sequence type is not standard"_port_en_US
);
6136 Say("A sequence type data component must either be of an intrinsic type or a derived sequence type"_err_en_US
);
6141 Walk(std::get
<std::list
<parser::ComponentOrFill
>>(x
.t
));
6144 bool DeclarationVisitor::Pre(const parser::ProcComponentDefStmt
&) {
6145 CHECK(!interfaceName_
);
6148 void DeclarationVisitor::Post(const parser::ProcComponentDefStmt
&) {
6149 interfaceName_
= nullptr;
6151 bool DeclarationVisitor::Pre(const parser::ProcPointerInit
&x
) {
6152 if (auto *name
{std::get_if
<parser::Name
>(&x
.u
)}) {
6153 return !NameIsKnownOrIntrinsic(*name
) && !CheckUseError(*name
);
6155 const auto &null
{DEREF(std::get_if
<parser::NullInit
>(&x
.u
))};
6157 if (auto nullInit
{EvaluateExpr(null
)}) {
6158 if (!evaluate::IsNullPointer(*nullInit
)) {
6159 Say(null
.v
.value().source
,
6160 "Procedure pointer initializer must be a name or intrinsic NULL()"_err_en_US
);
6166 void DeclarationVisitor::Post(const parser::ProcInterface
&x
) {
6167 if (auto *name
{std::get_if
<parser::Name
>(&x
.u
)}) {
6168 interfaceName_
= name
;
6169 NoteInterfaceName(*name
);
6172 void DeclarationVisitor::Post(const parser::ProcDecl
&x
) {
6173 const auto &name
{std::get
<parser::Name
>(x
.t
)};
6174 // Don't use BypassGeneric or GetUltimate on this symbol, they can
6175 // lead to unusable names in module files.
6176 const Symbol
*procInterface
{
6177 interfaceName_
? interfaceName_
->symbol
: nullptr};
6178 auto attrs
{HandleSaveName(name
.source
, GetAttrs())};
6179 DerivedTypeDetails
*dtDetails
{nullptr};
6180 if (Symbol
* symbol
{currScope().symbol()}) {
6181 dtDetails
= symbol
->detailsIf
<DerivedTypeDetails
>();
6184 attrs
.set(Attr::EXTERNAL
);
6186 Symbol
&symbol
{DeclareProcEntity(name
, attrs
, procInterface
)};
6187 SetCUDADataAttr(name
.source
, symbol
, cudaDataAttr()); // for error
6188 symbol
.ReplaceName(name
.source
);
6190 dtDetails
->add_component(symbol
);
6192 DeclaredPossibleSpecificProc(symbol
);
6195 bool DeclarationVisitor::Pre(const parser::TypeBoundProcedurePart
&) {
6196 derivedTypeInfo_
.sawContains
= true;
6200 // Resolve binding names from type-bound generics, saved in genericBindings_.
6201 void DeclarationVisitor::Post(const parser::TypeBoundProcedurePart
&) {
6202 // track specifics seen for the current generic to detect duplicates:
6203 const Symbol
*currGeneric
{nullptr};
6204 std::set
<SourceName
> specifics
;
6205 for (const auto &[generic
, bindingName
] : genericBindings_
) {
6206 if (generic
!= currGeneric
) {
6207 currGeneric
= generic
;
6210 auto [it
, inserted
]{specifics
.insert(bindingName
->source
)};
6212 Say(*bindingName
, // C773
6213 "Binding name '%s' was already specified for generic '%s'"_err_en_US
,
6214 bindingName
->source
, generic
->name())
6215 .Attach(*it
, "Previous specification of '%s'"_en_US
, *it
);
6218 auto *symbol
{FindInTypeOrParents(*bindingName
)};
6220 Say(*bindingName
, // C772
6221 "Binding name '%s' not found in this derived type"_err_en_US
);
6222 } else if (!symbol
->has
<ProcBindingDetails
>()) {
6223 SayWithDecl(*bindingName
, *symbol
, // C772
6224 "'%s' is not the name of a specific binding of this type"_err_en_US
);
6226 generic
->get
<GenericDetails
>().AddSpecificProc(
6227 *symbol
, bindingName
->source
);
6230 genericBindings_
.clear();
6233 void DeclarationVisitor::Post(const parser::ContainsStmt
&) {
6234 if (derivedTypeInfo_
.sequence
) {
6235 Say("A sequence type may not have a CONTAINS statement"_err_en_US
); // C740
6239 void DeclarationVisitor::Post(
6240 const parser::TypeBoundProcedureStmt::WithoutInterface
&x
) {
6241 if (GetAttrs().test(Attr::DEFERRED
)) { // C783
6242 Say("DEFERRED is only allowed when an interface-name is provided"_err_en_US
);
6244 for (auto &declaration
: x
.declarations
) {
6245 auto &bindingName
{std::get
<parser::Name
>(declaration
.t
)};
6246 auto &optName
{std::get
<std::optional
<parser::Name
>>(declaration
.t
)};
6247 const parser::Name
&procedureName
{optName
? *optName
: bindingName
};
6248 Symbol
*procedure
{FindSymbol(procedureName
)};
6250 procedure
= NoteInterfaceName(procedureName
);
6253 const Symbol
&bindTo
{BypassGeneric(*procedure
)};
6254 if (auto *s
{MakeTypeSymbol(bindingName
, ProcBindingDetails
{bindTo
})}) {
6256 if (GetAttrs().test(Attr::DEFERRED
)) {
6257 context().SetError(*s
);
6264 void DeclarationVisitor::CheckBindings(
6265 const parser::TypeBoundProcedureStmt::WithoutInterface
&tbps
) {
6266 CHECK(currScope().IsDerivedType());
6267 for (auto &declaration
: tbps
.declarations
) {
6268 auto &bindingName
{std::get
<parser::Name
>(declaration
.t
)};
6269 if (Symbol
* binding
{FindInScope(bindingName
)}) {
6270 if (auto *details
{binding
->detailsIf
<ProcBindingDetails
>()}) {
6271 const Symbol
&ultimate
{details
->symbol().GetUltimate()};
6272 const Symbol
&procedure
{BypassGeneric(ultimate
)};
6273 if (&procedure
!= &ultimate
) {
6274 details
->ReplaceSymbol(procedure
);
6276 if (!CanBeTypeBoundProc(procedure
)) {
6277 if (details
->symbol().name() != binding
->name()) {
6278 Say(binding
->name(),
6279 "The binding of '%s' ('%s') must be either an accessible "
6280 "module procedure or an external procedure with "
6281 "an explicit interface"_err_en_US
,
6282 binding
->name(), details
->symbol().name());
6284 Say(binding
->name(),
6285 "'%s' must be either an accessible module procedure "
6286 "or an external procedure with an explicit interface"_err_en_US
,
6289 context().SetError(*binding
);
6296 void DeclarationVisitor::Post(
6297 const parser::TypeBoundProcedureStmt::WithInterface
&x
) {
6298 if (!GetAttrs().test(Attr::DEFERRED
)) { // C783
6299 Say("DEFERRED is required when an interface-name is provided"_err_en_US
);
6301 if (Symbol
* interface
{NoteInterfaceName(x
.interfaceName
)}) {
6302 for (auto &bindingName
: x
.bindingNames
) {
6304 MakeTypeSymbol(bindingName
, ProcBindingDetails
{*interface
})}) {
6306 if (!GetAttrs().test(Attr::DEFERRED
)) {
6307 context().SetError(*s
);
6314 bool DeclarationVisitor::Pre(const parser::FinalProcedureStmt
&x
) {
6315 if (currScope().IsDerivedType() && currScope().symbol()) {
6316 if (auto *details
{currScope().symbol()->detailsIf
<DerivedTypeDetails
>()}) {
6317 for (const auto &subrName
: x
.v
) {
6318 Symbol
*symbol
{FindSymbol(subrName
)};
6320 // FINAL procedures must be module subroutines
6321 symbol
= &MakeSymbol(
6322 currScope().parent(), subrName
.source
, Attrs
{Attr::MODULE
});
6323 Resolve(subrName
, symbol
);
6324 symbol
->set_details(ProcEntityDetails
{});
6325 symbol
->set(Symbol::Flag::Subroutine
);
6327 if (auto pair
{details
->finals().emplace(subrName
.source
, *symbol
)};
6328 !pair
.second
) { // C787
6329 Say(subrName
.source
,
6330 "FINAL subroutine '%s' already appeared in this derived type"_err_en_US
,
6332 .Attach(pair
.first
->first
,
6333 "earlier appearance of this FINAL subroutine"_en_US
);
6341 bool DeclarationVisitor::Pre(const parser::TypeBoundGenericStmt
&x
) {
6342 const auto &accessSpec
{std::get
<std::optional
<parser::AccessSpec
>>(x
.t
)};
6343 const auto &genericSpec
{std::get
<Indirection
<parser::GenericSpec
>>(x
.t
)};
6344 const auto &bindingNames
{std::get
<std::list
<parser::Name
>>(x
.t
)};
6345 GenericSpecInfo info
{genericSpec
.value()};
6346 SourceName symbolName
{info
.symbolName()};
6347 bool isPrivate
{accessSpec
? accessSpec
->v
== parser::AccessSpec::Kind::Private
6348 : derivedTypeInfo_
.privateBindings
};
6349 auto *genericSymbol
{FindInScope(symbolName
)};
6350 if (genericSymbol
) {
6351 if (!genericSymbol
->has
<GenericDetails
>()) {
6352 genericSymbol
= nullptr; // MakeTypeSymbol will report the error below
6355 // look in ancestor types for a generic of the same name
6356 for (const auto &name
: GetAllNames(context(), symbolName
)) {
6357 if (Symbol
* inherited
{currScope().FindComponent(SourceName
{name
})}) {
6358 if (inherited
->has
<GenericDetails
>()) {
6359 CheckAccessibility(symbolName
, isPrivate
, *inherited
); // C771
6362 "Type bound generic procedure '%s' may not have the same name as a non-generic symbol inherited from an ancestor type"_err_en_US
)
6363 .Attach(inherited
->name(), "Inherited symbol"_en_US
);
6369 if (genericSymbol
) {
6370 CheckAccessibility(symbolName
, isPrivate
, *genericSymbol
); // C771
6372 genericSymbol
= MakeTypeSymbol(symbolName
, GenericDetails
{});
6373 if (!genericSymbol
) {
6377 SetExplicitAttr(*genericSymbol
, Attr::PRIVATE
);
6380 for (const parser::Name
&bindingName
: bindingNames
) {
6381 genericBindings_
.emplace(genericSymbol
, &bindingName
);
6383 info
.Resolve(genericSymbol
);
6387 // DEC STRUCTUREs are handled thus to allow for nested definitions.
6388 bool DeclarationVisitor::Pre(const parser::StructureDef
&def
) {
6389 const auto &structureStatement
{
6390 std::get
<parser::Statement
<parser::StructureStmt
>>(def
.t
)};
6391 auto saveDerivedTypeInfo
{derivedTypeInfo_
};
6392 derivedTypeInfo_
= {};
6393 derivedTypeInfo_
.isStructure
= true;
6394 derivedTypeInfo_
.sequence
= true;
6395 Scope
*previousStructure
{nullptr};
6396 if (saveDerivedTypeInfo
.isStructure
) {
6397 previousStructure
= &currScope();
6400 const parser::StructureStmt
&structStmt
{structureStatement
.statement
};
6401 const auto &name
{std::get
<std::optional
<parser::Name
>>(structStmt
.t
)};
6403 // Construct a distinct generated name for an anonymous structure
6404 auto &mutableName
{const_cast<std::optional
<parser::Name
> &>(name
)};
6405 mutableName
.emplace(
6406 parser::Name
{context().GetTempName(currScope()), nullptr});
6408 auto &symbol
{MakeSymbol(*name
, DerivedTypeDetails
{})};
6409 symbol
.ReplaceName(name
->source
);
6410 symbol
.get
<DerivedTypeDetails
>().set_sequence(true);
6411 symbol
.get
<DerivedTypeDetails
>().set_isDECStructure(true);
6412 derivedTypeInfo_
.type
= &symbol
;
6413 PushScope(Scope::Kind::DerivedType
, &symbol
);
6414 const auto &fields
{std::get
<std::list
<parser::StructureField
>>(def
.t
)};
6417 // Complete the definition
6418 DerivedTypeSpec derivedTypeSpec
{symbol
.name(), symbol
};
6419 derivedTypeSpec
.set_scope(DEREF(symbol
.scope()));
6420 derivedTypeSpec
.CookParameters(GetFoldingContext());
6421 derivedTypeSpec
.EvaluateParameters(context());
6422 DeclTypeSpec
&type
{currScope().MakeDerivedType(
6423 DeclTypeSpec::TypeDerived
, std::move(derivedTypeSpec
))};
6424 type
.derivedTypeSpec().Instantiate(currScope());
6425 // Restore previous structure definition context, if any
6426 derivedTypeInfo_
= saveDerivedTypeInfo
;
6427 if (previousStructure
) {
6428 PushScope(*previousStructure
);
6430 // Handle any entity declarations on the STRUCTURE statement
6431 const auto &decls
{std::get
<std::list
<parser::EntityDecl
>>(structStmt
.t
)};
6432 if (!decls
.empty()) {
6434 SetDeclTypeSpec(type
);
6441 bool DeclarationVisitor::Pre(const parser::Union::UnionStmt
&) {
6442 Say("support for UNION"_todo_en_US
); // TODO
6446 bool DeclarationVisitor::Pre(const parser::StructureField
&x
) {
6447 if (std::holds_alternative
<parser::Statement
<parser::DataComponentDefStmt
>>(
6454 void DeclarationVisitor::Post(const parser::StructureField
&x
) {
6455 if (std::holds_alternative
<parser::Statement
<parser::DataComponentDefStmt
>>(
6461 bool DeclarationVisitor::Pre(const parser::AllocateStmt
&) {
6462 BeginDeclTypeSpec();
6465 void DeclarationVisitor::Post(const parser::AllocateStmt
&) {
6469 bool DeclarationVisitor::Pre(const parser::StructureConstructor
&x
) {
6470 auto &parsedType
{std::get
<parser::DerivedTypeSpec
>(x
.t
)};
6471 const DeclTypeSpec
*type
{ProcessTypeSpec(parsedType
)};
6475 const DerivedTypeSpec
*spec
{type
->AsDerived()};
6476 const Scope
*typeScope
{spec
? spec
->scope() : nullptr};
6481 // N.B C7102 is implicitly enforced by having inaccessible types not
6482 // being found in resolution.
6483 // More constraints are enforced in expression.cpp so that they
6484 // can apply to structure constructors that have been converted
6485 // from misparsed function references.
6486 for (const auto &component
:
6487 std::get
<std::list
<parser::ComponentSpec
>>(x
.t
)) {
6488 // Visit the component spec expression, but not the keyword, since
6489 // we need to resolve its symbol in the scope of the derived type.
6490 Walk(std::get
<parser::ComponentDataSource
>(component
.t
));
6491 if (const auto &kw
{std::get
<std::optional
<parser::Keyword
>>(component
.t
)}) {
6492 FindInTypeOrParents(*typeScope
, kw
->v
);
6498 bool DeclarationVisitor::Pre(const parser::BasedPointer
&) {
6503 void DeclarationVisitor::Post(const parser::BasedPointer
&bp
) {
6504 const parser::ObjectName
&pointerName
{std::get
<0>(bp
.t
)};
6505 auto *pointer
{FindSymbol(pointerName
)};
6507 pointer
= &MakeSymbol(pointerName
, ObjectEntityDetails
{});
6508 } else if (!ConvertToObjectEntity(*pointer
)) {
6509 SayWithDecl(pointerName
, *pointer
, "'%s' is not a variable"_err_en_US
);
6510 } else if (IsNamedConstant(*pointer
)) {
6511 SayWithDecl(pointerName
, *pointer
,
6512 "'%s' is a named constant and may not be a Cray pointer"_err_en_US
);
6513 } else if (pointer
->Rank() > 0) {
6515 pointerName
, *pointer
, "Cray pointer '%s' must be a scalar"_err_en_US
);
6516 } else if (pointer
->test(Symbol::Flag::CrayPointee
)) {
6518 "'%s' cannot be a Cray pointer as it is already a Cray pointee"_err_en_US
);
6520 pointer
->set(Symbol::Flag::CrayPointer
);
6521 const DeclTypeSpec
&pointerType
{MakeNumericType(
6522 TypeCategory::Integer
, context().defaultKinds().subscriptIntegerKind())};
6523 const auto *type
{pointer
->GetType()};
6525 pointer
->SetType(pointerType
);
6526 } else if (*type
!= pointerType
) {
6527 Say(pointerName
.source
, "Cray pointer '%s' must have type %s"_err_en_US
,
6528 pointerName
.source
, pointerType
.AsFortran());
6530 const parser::ObjectName
&pointeeName
{std::get
<1>(bp
.t
)};
6531 DeclareObjectEntity(pointeeName
);
6532 if (Symbol
* pointee
{pointeeName
.symbol
}) {
6533 if (!ConvertToObjectEntity(*pointee
)) {
6536 if (IsNamedConstant(*pointee
)) {
6538 "'%s' is a named constant and may not be a Cray pointee"_err_en_US
);
6541 if (pointee
->test(Symbol::Flag::CrayPointer
)) {
6543 "'%s' cannot be a Cray pointee as it is already a Cray pointer"_err_en_US
);
6544 } else if (pointee
->test(Symbol::Flag::CrayPointee
)) {
6545 Say(pointeeName
, "'%s' was already declared as a Cray pointee"_err_en_US
);
6547 pointee
->set(Symbol::Flag::CrayPointee
);
6549 if (const auto *pointeeType
{pointee
->GetType()}) {
6550 if (const auto *derived
{pointeeType
->AsDerived()}) {
6551 if (!IsSequenceOrBindCType(derived
)) {
6552 context().Warn(common::LanguageFeature::NonSequenceCrayPointee
,
6554 "Type of Cray pointee '%s' is a derived type that is neither SEQUENCE nor BIND(C)"_warn_en_US
,
6555 pointeeName
.source
);
6559 currScope().add_crayPointer(pointeeName
.source
, *pointer
);
6563 bool DeclarationVisitor::Pre(const parser::NamelistStmt::Group
&x
) {
6564 if (!CheckNotInBlock("NAMELIST")) { // C1107
6567 const auto &groupName
{std::get
<parser::Name
>(x
.t
)};
6568 auto *groupSymbol
{FindInScope(groupName
)};
6569 if (!groupSymbol
|| !groupSymbol
->has
<NamelistDetails
>()) {
6570 groupSymbol
= &MakeSymbol(groupName
, NamelistDetails
{});
6571 groupSymbol
->ReplaceName(groupName
.source
);
6573 // Name resolution of group items is deferred to FinishNamelists()
6574 // so that host association is handled correctly.
6575 GetDeferredDeclarationState(true)->namelistGroups
.emplace_back(&x
);
6579 void DeclarationVisitor::FinishNamelists() {
6580 if (auto *deferred
{GetDeferredDeclarationState()}) {
6581 for (const parser::NamelistStmt::Group
*group
: deferred
->namelistGroups
) {
6582 if (auto *groupSymbol
{FindInScope(std::get
<parser::Name
>(group
->t
))}) {
6583 if (auto *details
{groupSymbol
->detailsIf
<NamelistDetails
>()}) {
6584 for (const auto &name
: std::get
<std::list
<parser::Name
>>(group
->t
)) {
6585 auto *symbol
{FindSymbol(name
)};
6587 symbol
= &MakeSymbol(name
, ObjectEntityDetails
{});
6588 ApplyImplicitRules(*symbol
);
6589 } else if (!ConvertToObjectEntity(symbol
->GetUltimate())) {
6590 SayWithDecl(name
, *symbol
, "'%s' is not a variable"_err_en_US
);
6591 context().SetError(*groupSymbol
);
6593 symbol
->GetUltimate().set(Symbol::Flag::InNamelist
);
6594 details
->add_object(*symbol
);
6599 deferred
->namelistGroups
.clear();
6603 bool DeclarationVisitor::Pre(const parser::IoControlSpec
&x
) {
6604 if (const auto *name
{std::get_if
<parser::Name
>(&x
.u
)}) {
6605 auto *symbol
{FindSymbol(*name
)};
6607 Say(*name
, "Namelist group '%s' not found"_err_en_US
);
6608 } else if (!symbol
->GetUltimate().has
<NamelistDetails
>()) {
6610 *name
, *symbol
, "'%s' is not the name of a namelist group"_err_en_US
);
6616 bool DeclarationVisitor::Pre(const parser::CommonStmt::Block
&x
) {
6617 CheckNotInBlock("COMMON"); // C1107
6621 bool DeclarationVisitor::Pre(const parser::CommonBlockObject
&) {
6626 void DeclarationVisitor::Post(const parser::CommonBlockObject
&x
) {
6627 const auto &name
{std::get
<parser::Name
>(x
.t
)};
6628 DeclareObjectEntity(name
);
6629 auto pair
{specPartState_
.commonBlockObjects
.insert(name
.source
)};
6631 const SourceName
&prev
{*pair
.first
};
6632 Say2(name
.source
, "'%s' is already in a COMMON block"_err_en_US
, prev
,
6633 "Previous occurrence of '%s' in a COMMON block"_en_US
);
6637 bool DeclarationVisitor::Pre(const parser::EquivalenceStmt
&x
) {
6638 // save equivalence sets to be processed after specification part
6639 if (CheckNotInBlock("EQUIVALENCE")) { // C1107
6640 for (const std::list
<parser::EquivalenceObject
> &set
: x
.v
) {
6641 specPartState_
.equivalenceSets
.push_back(&set
);
6644 return false; // don't implicitly declare names yet
6647 void DeclarationVisitor::CheckEquivalenceSets() {
6648 EquivalenceSets equivSets
{context()};
6649 inEquivalenceStmt_
= true;
6650 for (const auto *set
: specPartState_
.equivalenceSets
) {
6651 const auto &source
{set
->front().v
.value().source
};
6652 if (set
->size() <= 1) { // R871
6653 Say(source
, "Equivalence set must have more than one object"_err_en_US
);
6655 for (const parser::EquivalenceObject
&object
: *set
) {
6656 const auto &designator
{object
.v
.value()};
6657 // The designator was not resolved when it was encountered, so do it now.
6658 // AnalyzeExpr causes array sections to be changed to substrings as needed
6660 if (AnalyzeExpr(context(), designator
)) {
6661 equivSets
.AddToSet(designator
);
6664 equivSets
.FinishSet(source
);
6666 inEquivalenceStmt_
= false;
6667 for (auto &set
: equivSets
.sets()) {
6669 currScope().add_equivalenceSet(std::move(set
));
6672 specPartState_
.equivalenceSets
.clear();
6675 bool DeclarationVisitor::Pre(const parser::SaveStmt
&x
) {
6677 specPartState_
.saveInfo
.saveAll
= currStmtSource();
6678 currScope().set_hasSAVE();
6680 for (const parser::SavedEntity
&y
: x
.v
) {
6681 auto kind
{std::get
<parser::SavedEntity::Kind
>(y
.t
)};
6682 const auto &name
{std::get
<parser::Name
>(y
.t
)};
6683 if (kind
== parser::SavedEntity::Kind::Common
) {
6684 MakeCommonBlockSymbol(name
);
6685 AddSaveName(specPartState_
.saveInfo
.commons
, name
.source
);
6687 HandleAttributeStmt(Attr::SAVE
, name
);
6694 void DeclarationVisitor::CheckSaveStmts() {
6695 for (const SourceName
&name
: specPartState_
.saveInfo
.entities
) {
6696 auto *symbol
{FindInScope(name
)};
6698 // error was reported
6699 } else if (specPartState_
.saveInfo
.saveAll
) {
6700 // C889 - note that pgi, ifort, xlf do not enforce this constraint
6701 if (context().ShouldWarn(common::LanguageFeature::RedundantAttribute
)) {
6703 "Explicit SAVE of '%s' is redundant due to global SAVE statement"_warn_en_US
,
6704 *specPartState_
.saveInfo
.saveAll
, "Global SAVE statement"_en_US
)
6705 .set_languageFeature(common::LanguageFeature::RedundantAttribute
);
6707 } else if (!IsSaved(*symbol
)) {
6708 SetExplicitAttr(*symbol
, Attr::SAVE
);
6711 for (const SourceName
&name
: specPartState_
.saveInfo
.commons
) {
6712 if (auto *symbol
{currScope().FindCommonBlock(name
)}) {
6713 auto &objects
{symbol
->get
<CommonBlockDetails
>().objects()};
6714 if (objects
.empty()) {
6715 if (currScope().kind() != Scope::Kind::BlockConstruct
) {
6717 "'%s' appears as a COMMON block in a SAVE statement but not in"
6718 " a COMMON statement"_err_en_US
);
6721 "SAVE statement in BLOCK construct may not contain a"
6722 " common block name '%s'"_err_en_US
);
6725 for (auto &object
: symbol
->get
<CommonBlockDetails
>().objects()) {
6726 if (!IsSaved(*object
)) {
6727 SetImplicitAttr(*object
, Attr::SAVE
);
6733 specPartState_
.saveInfo
= {};
6736 // Record SAVEd names in specPartState_.saveInfo.entities.
6737 Attrs
DeclarationVisitor::HandleSaveName(const SourceName
&name
, Attrs attrs
) {
6738 if (attrs
.test(Attr::SAVE
)) {
6739 AddSaveName(specPartState_
.saveInfo
.entities
, name
);
6744 // Record a name in a set of those to be saved.
6745 void DeclarationVisitor::AddSaveName(
6746 std::set
<SourceName
> &set
, const SourceName
&name
) {
6747 auto pair
{set
.insert(name
)};
6749 context().ShouldWarn(common::LanguageFeature::RedundantAttribute
)) {
6750 Say2(name
, "SAVE attribute was already specified on '%s'"_warn_en_US
,
6751 *pair
.first
, "Previous specification of SAVE attribute"_en_US
)
6752 .set_languageFeature(common::LanguageFeature::RedundantAttribute
);
6756 // Check types of common block objects, now that they are known.
6757 void DeclarationVisitor::CheckCommonBlocks() {
6758 // check for empty common blocks
6759 for (const auto &pair
: currScope().commonBlocks()) {
6760 const auto &symbol
{*pair
.second
};
6761 if (symbol
.get
<CommonBlockDetails
>().objects().empty() &&
6762 symbol
.attrs().test(Attr::BIND_C
)) {
6764 "'%s' appears as a COMMON block in a BIND statement but not in"
6765 " a COMMON statement"_err_en_US
);
6768 // check objects in common blocks
6769 for (const auto &name
: specPartState_
.commonBlockObjects
) {
6770 const auto *symbol
{currScope().FindSymbol(name
)};
6774 const auto &attrs
{symbol
->attrs()};
6775 if (attrs
.test(Attr::ALLOCATABLE
)) {
6777 "ALLOCATABLE object '%s' may not appear in a COMMON block"_err_en_US
);
6778 } else if (attrs
.test(Attr::BIND_C
)) {
6780 "Variable '%s' with BIND attribute may not appear in a COMMON block"_err_en_US
);
6781 } else if (IsNamedConstant(*symbol
)) {
6783 "A named constant '%s' may not appear in a COMMON block"_err_en_US
);
6784 } else if (IsDummy(*symbol
)) {
6786 "Dummy argument '%s' may not appear in a COMMON block"_err_en_US
);
6787 } else if (symbol
->IsFuncResult()) {
6789 "Function result '%s' may not appear in a COMMON block"_err_en_US
);
6790 } else if (const DeclTypeSpec
* type
{symbol
->GetType()}) {
6791 if (type
->category() == DeclTypeSpec::ClassStar
) {
6793 "Unlimited polymorphic pointer '%s' may not appear in a COMMON block"_err_en_US
);
6794 } else if (const auto *derived
{type
->AsDerived()}) {
6795 if (!IsSequenceOrBindCType(derived
)) {
6797 "Derived type '%s' in COMMON block must have the BIND or"
6798 " SEQUENCE attribute"_err_en_US
);
6800 UnorderedSymbolSet typeSet
;
6801 CheckCommonBlockDerivedType(name
, derived
->typeSymbol(), typeSet
);
6805 specPartState_
.commonBlockObjects
= {};
6808 Symbol
&DeclarationVisitor::MakeCommonBlockSymbol(const parser::Name
&name
) {
6809 return Resolve(name
, currScope().MakeCommonBlock(name
.source
));
6811 Symbol
&DeclarationVisitor::MakeCommonBlockSymbol(
6812 const std::optional
<parser::Name
> &name
) {
6814 return MakeCommonBlockSymbol(*name
);
6816 return MakeCommonBlockSymbol(parser::Name
{});
6820 bool DeclarationVisitor::NameIsKnownOrIntrinsic(const parser::Name
&name
) {
6821 return FindSymbol(name
) || HandleUnrestrictedSpecificIntrinsicFunction(name
);
6824 // Check if this derived type can be in a COMMON block.
6825 void DeclarationVisitor::CheckCommonBlockDerivedType(const SourceName
&name
,
6826 const Symbol
&typeSymbol
, UnorderedSymbolSet
&typeSet
) {
6827 if (auto iter
{typeSet
.find(SymbolRef
{typeSymbol
})}; iter
!= typeSet
.end()) {
6830 typeSet
.emplace(typeSymbol
);
6831 if (const auto *scope
{typeSymbol
.scope()}) {
6832 for (const auto &pair
: *scope
) {
6833 const Symbol
&component
{*pair
.second
};
6834 if (component
.attrs().test(Attr::ALLOCATABLE
)) {
6836 "Derived type variable '%s' may not appear in a COMMON block"
6837 " due to ALLOCATABLE component"_err_en_US
,
6838 component
.name(), "Component with ALLOCATABLE attribute"_en_US
);
6841 const auto *details
{component
.detailsIf
<ObjectEntityDetails
>()};
6842 if (component
.test(Symbol::Flag::InDataStmt
) ||
6843 (details
&& details
->init())) {
6845 "Derived type variable '%s' may not appear in a COMMON block due to component with default initialization"_err_en_US
,
6846 component
.name(), "Component with default initialization"_en_US
);
6850 if (const auto *type
{details
->type()}) {
6851 if (const auto *derived
{type
->AsDerived()}) {
6852 const Symbol
&derivedTypeSymbol
{derived
->typeSymbol()};
6853 CheckCommonBlockDerivedType(name
, derivedTypeSymbol
, typeSet
);
6861 bool DeclarationVisitor::HandleUnrestrictedSpecificIntrinsicFunction(
6862 const parser::Name
&name
) {
6863 if (auto interface
{context().intrinsics().IsSpecificIntrinsicFunction(
6864 name
.source
.ToString())}) {
6865 // Unrestricted specific intrinsic function names (e.g., "cos")
6866 // are acceptable as procedure interfaces. The presence of the
6867 // INTRINSIC flag will cause this symbol to have a complete interface
6868 // recreated for it later on demand, but capturing its result type here
6869 // will make GetType() return a correct result without having to
6870 // probe the intrinsics table again.
6871 Symbol
&symbol
{MakeSymbol(InclusiveScope(), name
.source
, Attrs
{})};
6872 SetImplicitAttr(symbol
, Attr::INTRINSIC
);
6873 CHECK(interface
->functionResult
.has_value());
6874 evaluate::DynamicType dyType
{
6875 DEREF(interface
->functionResult
->GetTypeAndShape()).type()};
6876 CHECK(common::IsNumericTypeCategory(dyType
.category()));
6877 const DeclTypeSpec
&typeSpec
{
6878 MakeNumericType(dyType
.category(), dyType
.kind())};
6879 ProcEntityDetails details
;
6880 details
.set_type(typeSpec
);
6881 symbol
.set_details(std::move(details
));
6882 symbol
.set(Symbol::Flag::Function
);
6883 if (interface
->IsElemental()) {
6884 SetExplicitAttr(symbol
, Attr::ELEMENTAL
);
6886 if (interface
->IsPure()) {
6887 SetExplicitAttr(symbol
, Attr::PURE
);
6889 Resolve(name
, symbol
);
6896 // Checks for all locality-specs: LOCAL, LOCAL_INIT, and SHARED
6897 bool DeclarationVisitor::PassesSharedLocalityChecks(
6898 const parser::Name
&name
, Symbol
&symbol
) {
6899 if (!IsVariableName(symbol
)) {
6900 SayLocalMustBeVariable(name
, symbol
); // C1124
6903 if (symbol
.owner() == currScope()) { // C1125 and C1126
6904 SayAlreadyDeclared(name
, symbol
);
6910 // Checks for locality-specs LOCAL, LOCAL_INIT, and REDUCE
6911 bool DeclarationVisitor::PassesLocalityChecks(
6912 const parser::Name
&name
, Symbol
&symbol
, Symbol::Flag flag
) {
6913 bool isReduce
{flag
== Symbol::Flag::LocalityReduce
};
6914 const char *specName
{
6915 flag
== Symbol::Flag::LocalityLocalInit
? "LOCAL_INIT" : "LOCAL"};
6916 if (IsAllocatable(symbol
) && !isReduce
) { // F'2023 C1130
6917 SayWithDecl(name
, symbol
,
6918 "ALLOCATABLE variable '%s' not allowed in a %s locality-spec"_err_en_US
,
6922 if (IsOptional(symbol
)) { // F'2023 C1130-C1131
6923 SayWithDecl(name
, symbol
,
6924 "OPTIONAL argument '%s' not allowed in a locality-spec"_err_en_US
);
6927 if (IsIntentIn(symbol
)) { // F'2023 C1130-C1131
6928 SayWithDecl(name
, symbol
,
6929 "INTENT IN argument '%s' not allowed in a locality-spec"_err_en_US
);
6932 if (IsFinalizable(symbol
) && !isReduce
) { // F'2023 C1130
6933 SayWithDecl(name
, symbol
,
6934 "Finalizable variable '%s' not allowed in a %s locality-spec"_err_en_US
,
6938 if (evaluate::IsCoarray(symbol
) && !isReduce
) { // F'2023 C1130
6939 SayWithDecl(name
, symbol
,
6940 "Coarray '%s' not allowed in a %s locality-spec"_err_en_US
, specName
);
6943 if (const DeclTypeSpec
* type
{symbol
.GetType()}) {
6944 if (type
->IsPolymorphic() && IsDummy(symbol
) && !IsPointer(symbol
) &&
6945 !isReduce
) { // F'2023 C1130
6946 SayWithDecl(name
, symbol
,
6947 "Nonpointer polymorphic argument '%s' not allowed in a %s locality-spec"_err_en_US
,
6952 if (symbol
.attrs().test(Attr::ASYNCHRONOUS
) && isReduce
) { // F'2023 C1131
6953 SayWithDecl(name
, symbol
,
6954 "ASYNCHRONOUS variable '%s' not allowed in a REDUCE locality-spec"_err_en_US
);
6957 if (symbol
.attrs().test(Attr::VOLATILE
) && isReduce
) { // F'2023 C1131
6958 SayWithDecl(name
, symbol
,
6959 "VOLATILE variable '%s' not allowed in a REDUCE locality-spec"_err_en_US
);
6962 if (IsAssumedSizeArray(symbol
)) { // F'2023 C1130-C1131
6963 SayWithDecl(name
, symbol
,
6964 "Assumed size array '%s' not allowed in a locality-spec"_err_en_US
);
6967 if (std::optional
<Message
> whyNot
{WhyNotDefinable(
6968 name
.source
, currScope(), DefinabilityFlags
{}, symbol
)}) {
6969 SayWithReason(name
, symbol
,
6970 "'%s' may not appear in a locality-spec because it is not definable"_err_en_US
,
6971 std::move(whyNot
->set_severity(parser::Severity::Because
)));
6974 return PassesSharedLocalityChecks(name
, symbol
);
6977 Symbol
&DeclarationVisitor::FindOrDeclareEnclosingEntity(
6978 const parser::Name
&name
) {
6979 Symbol
*prev
{FindSymbol(name
)};
6981 // Declare the name as an object in the enclosing scope so that
6982 // the name can't be repurposed there later as something else.
6983 prev
= &MakeSymbol(InclusiveScope(), name
.source
, Attrs
{});
6984 ConvertToObjectEntity(*prev
);
6985 ApplyImplicitRules(*prev
);
6990 void DeclarationVisitor::DeclareLocalEntity(
6991 const parser::Name
&name
, Symbol::Flag flag
) {
6992 Symbol
&prev
{FindOrDeclareEnclosingEntity(name
)};
6993 if (PassesLocalityChecks(name
, prev
, flag
)) {
6994 if (auto *symbol
{&MakeHostAssocSymbol(name
, prev
)}) {
7000 Symbol
*DeclarationVisitor::DeclareStatementEntity(
7001 const parser::DoVariable
&doVar
,
7002 const std::optional
<parser::IntegerTypeSpec
> &type
) {
7003 const parser::Name
&name
{doVar
.thing
.thing
};
7004 const DeclTypeSpec
*declTypeSpec
{nullptr};
7005 if (auto *prev
{FindSymbol(name
)}) {
7006 if (prev
->owner() == currScope()) {
7007 SayAlreadyDeclared(name
, *prev
);
7010 name
.symbol
= nullptr;
7011 // F'2023 19.4 p5 ambiguous rule about outer declarations
7012 declTypeSpec
= prev
->GetType();
7014 Symbol
&symbol
{DeclareEntity
<ObjectEntityDetails
>(name
, {})};
7015 if (!symbol
.has
<ObjectEntityDetails
>()) {
7016 return nullptr; // error was reported in DeclareEntity
7019 declTypeSpec
= ProcessTypeSpec(*type
);
7022 // Subtlety: Don't let a "*length" specifier (if any is pending) affect the
7023 // declaration of this implied DO loop control variable.
7025 common::ScopedSet(charInfo_
.length
, std::optional
<ParamValue
>{})};
7026 SetType(name
, *declTypeSpec
);
7028 ApplyImplicitRules(symbol
);
7030 return Resolve(name
, &symbol
);
7033 // Set the type of an entity or report an error.
7034 void DeclarationVisitor::SetType(
7035 const parser::Name
&name
, const DeclTypeSpec
&type
) {
7037 auto &symbol
{*name
.symbol
};
7038 if (charInfo_
.length
) { // Declaration has "*length" (R723)
7039 auto length
{std::move(*charInfo_
.length
)};
7040 charInfo_
.length
.reset();
7041 if (type
.category() == DeclTypeSpec::Character
) {
7042 auto kind
{type
.characterTypeSpec().kind()};
7043 // Recurse with correct type.
7045 currScope().MakeCharacterType(std::move(length
), std::move(kind
)));
7049 "A length specifier cannot be used to declare the non-character entity '%s'"_err_en_US
);
7052 if (auto *proc
{symbol
.detailsIf
<ProcEntityDetails
>()}) {
7053 if (proc
->procInterface()) {
7055 "'%s' has an explicit interface and may not also have a type"_err_en_US
);
7056 context().SetError(symbol
);
7060 auto *prevType
{symbol
.GetType()};
7062 if (symbol
.test(Symbol::Flag::InDataStmt
) && isImplicitNoneType()) {
7063 context().Warn(common::LanguageFeature::ForwardRefImplicitNoneData
,
7065 "'%s' appeared in a DATA statement before its type was declared under IMPLICIT NONE(TYPE)"_port_en_US
,
7068 symbol
.SetType(type
);
7069 } else if (symbol
.has
<UseDetails
>()) {
7070 // error recovery case, redeclaration of use-associated name
7071 } else if (HadForwardRef(symbol
)) {
7072 // error recovery after use of host-associated name
7073 } else if (!symbol
.test(Symbol::Flag::Implicit
)) {
7075 name
, symbol
, "The type of '%s' has already been declared"_err_en_US
);
7076 context().SetError(symbol
);
7077 } else if (type
!= *prevType
) {
7078 SayWithDecl(name
, symbol
,
7079 "The type of '%s' has already been implicitly declared"_err_en_US
);
7080 context().SetError(symbol
);
7082 symbol
.set(Symbol::Flag::Implicit
, false);
7086 std::optional
<DerivedTypeSpec
> DeclarationVisitor::ResolveDerivedType(
7087 const parser::Name
&name
) {
7088 Scope
&outer
{NonDerivedTypeScope()};
7089 Symbol
*symbol
{FindSymbol(outer
, name
)};
7090 Symbol
*ultimate
{symbol
? &symbol
->GetUltimate() : nullptr};
7091 auto *generic
{ultimate
? ultimate
->detailsIf
<GenericDetails
>() : nullptr};
7093 if (Symbol
* genDT
{generic
->derivedType()}) {
7098 if (!symbol
|| symbol
->has
<UnknownDetails
>() ||
7099 (generic
&& &ultimate
->owner() == &outer
)) {
7100 if (allowForwardReferenceToDerivedType()) {
7102 symbol
= &MakeSymbol(outer
, name
.source
, Attrs
{});
7103 Resolve(name
, *symbol
);
7104 } else if (generic
) {
7105 // forward ref to type with later homonymous generic
7106 symbol
= &outer
.MakeSymbol(name
.source
, Attrs
{}, UnknownDetails
{});
7107 generic
->set_derivedType(*symbol
);
7108 name
.symbol
= symbol
;
7110 DerivedTypeDetails details
;
7111 details
.set_isForwardReferenced(true);
7112 symbol
->set_details(std::move(details
));
7114 Say(name
, "Derived type '%s' not found"_err_en_US
);
7115 return std::nullopt
;
7117 } else if (&DEREF(symbol
).owner() != &outer
&&
7118 !ultimate
->has
<GenericDetails
>()) {
7119 // Prevent a later declaration in this scope of a host-associated
7121 outer
.add_importName(name
.source
);
7123 if (CheckUseError(name
)) {
7124 return std::nullopt
;
7125 } else if (symbol
->GetUltimate().has
<DerivedTypeDetails
>()) {
7126 return DerivedTypeSpec
{name
.source
, *symbol
};
7128 Say(name
, "'%s' is not a derived type"_err_en_US
);
7129 return std::nullopt
;
7133 std::optional
<DerivedTypeSpec
> DeclarationVisitor::ResolveExtendsType(
7134 const parser::Name
&typeName
, const parser::Name
*extendsName
) {
7136 if (typeName
.source
== extendsName
->source
) {
7137 Say(extendsName
->source
,
7138 "Derived type '%s' cannot extend itself"_err_en_US
);
7139 } else if (auto dtSpec
{ResolveDerivedType(*extendsName
)}) {
7140 if (!dtSpec
->IsForwardReferenced()) {
7143 Say(typeName
.source
,
7144 "Derived type '%s' cannot extend type '%s' that has not yet been defined"_err_en_US
,
7145 typeName
.source
, extendsName
->source
);
7148 return std::nullopt
;
7151 Symbol
*DeclarationVisitor::NoteInterfaceName(const parser::Name
&name
) {
7152 // The symbol is checked later by CheckExplicitInterface() and
7153 // CheckBindings(). It can be a forward reference.
7154 if (!NameIsKnownOrIntrinsic(name
)) {
7155 Symbol
&symbol
{MakeSymbol(InclusiveScope(), name
.source
, Attrs
{})};
7156 Resolve(name
, symbol
);
7161 void DeclarationVisitor::CheckExplicitInterface(const parser::Name
&name
) {
7162 if (const Symbol
* symbol
{name
.symbol
}) {
7163 const Symbol
&ultimate
{symbol
->GetUltimate()};
7164 if (!context().HasError(*symbol
) && !context().HasError(ultimate
) &&
7165 !BypassGeneric(ultimate
).HasExplicitInterface()) {
7167 "'%s' must be an abstract interface or a procedure with an explicit interface"_err_en_US
,
7173 // Create a symbol for a type parameter, component, or procedure binding in
7174 // the current derived type scope. Return false on error.
7175 Symbol
*DeclarationVisitor::MakeTypeSymbol(
7176 const parser::Name
&name
, Details
&&details
) {
7177 return Resolve(name
, MakeTypeSymbol(name
.source
, std::move(details
)));
7179 Symbol
*DeclarationVisitor::MakeTypeSymbol(
7180 const SourceName
&name
, Details
&&details
) {
7181 Scope
&derivedType
{currScope()};
7182 CHECK(derivedType
.IsDerivedType());
7183 if (auto *symbol
{FindInScope(derivedType
, name
)}) { // C742
7185 "Type parameter, component, or procedure binding '%s'"
7186 " already defined in this type"_err_en_US
,
7187 *symbol
, "Previous definition of '%s'"_en_US
);
7190 auto attrs
{GetAttrs()};
7191 // Apply binding-private-stmt if present and this is a procedure binding
7192 if (derivedTypeInfo_
.privateBindings
&&
7193 !attrs
.HasAny({Attr::PUBLIC
, Attr::PRIVATE
}) &&
7194 std::holds_alternative
<ProcBindingDetails
>(details
)) {
7195 attrs
.set(Attr::PRIVATE
);
7197 Symbol
&result
{MakeSymbol(name
, attrs
, std::move(details
))};
7198 SetCUDADataAttr(name
, result
, cudaDataAttr());
7203 // Return true if it is ok to declare this component in the current scope.
7204 // Otherwise, emit an error and return false.
7205 bool DeclarationVisitor::OkToAddComponent(
7206 const parser::Name
&name
, const Symbol
*extends
) {
7207 for (const Scope
*scope
{&currScope()}; scope
;) {
7208 CHECK(scope
->IsDerivedType());
7209 if (auto *prev
{FindInScope(*scope
, name
.source
)}) {
7210 std::optional
<parser::MessageFixedText
> msg
;
7211 std::optional
<common::UsageWarning
> warning
;
7212 if (context().HasError(*prev
)) { // don't pile on
7213 } else if (extends
) {
7214 msg
= "Type cannot be extended as it has a component named"
7216 } else if (CheckAccessibleSymbol(currScope(), *prev
)) {
7217 // inaccessible component -- redeclaration is ok
7218 if (context().ShouldWarn(
7219 common::UsageWarning::RedeclaredInaccessibleComponent
)) {
7221 "Component '%s' is inaccessibly declared in or as a parent of this derived type"_warn_en_US
;
7222 warning
= common::UsageWarning::RedeclaredInaccessibleComponent
;
7224 } else if (prev
->test(Symbol::Flag::ParentComp
)) {
7226 "'%s' is a parent type of this type and so cannot be a component"_err_en_US
;
7227 } else if (scope
== &currScope()) {
7229 "Component '%s' is already declared in this derived type"_err_en_US
;
7232 "Component '%s' is already declared in a parent of this derived type"_err_en_US
;
7235 auto &said
{Say2(name
, std::move(*msg
), *prev
,
7236 "Previous declaration of '%s'"_en_US
)};
7237 if (msg
->severity() == parser::Severity::Error
) {
7238 Resolve(name
, *prev
);
7242 said
.set_usageWarning(*warning
);
7246 if (scope
== &currScope() && extends
) {
7247 // The parent component has not yet been added to the scope.
7248 scope
= extends
->scope();
7250 scope
= scope
->GetDerivedTypeParent();
7256 ParamValue
DeclarationVisitor::GetParamValue(
7257 const parser::TypeParamValue
&x
, common::TypeParamAttr attr
) {
7258 return common::visit(
7260 [=](const parser::ScalarIntExpr
&x
) { // C704
7261 return ParamValue
{EvaluateIntExpr(x
), attr
};
7263 [=](const parser::Star
&) { return ParamValue::Assumed(attr
); },
7264 [=](const parser::TypeParamValue::Deferred
&) {
7265 return ParamValue::Deferred(attr
);
7271 // ConstructVisitor implementation
7273 void ConstructVisitor::ResolveIndexName(
7274 const parser::ConcurrentControl
&control
) {
7275 const parser::Name
&name
{std::get
<parser::Name
>(control
.t
)};
7276 auto *prev
{FindSymbol(name
)};
7278 if (prev
->owner() == currScope()) {
7279 SayAlreadyDeclared(name
, *prev
);
7281 } else if (prev
->owner().kind() == Scope::Kind::Forall
&&
7282 context().ShouldWarn(
7283 common::LanguageFeature::OddIndexVariableRestrictions
)) {
7284 SayWithDecl(name
, *prev
,
7285 "Index variable '%s' should not also be an index in an enclosing FORALL or DO CONCURRENT"_port_en_US
)
7286 .set_languageFeature(
7287 common::LanguageFeature::OddIndexVariableRestrictions
);
7289 name
.symbol
= nullptr;
7291 auto &symbol
{DeclareObjectEntity(name
)};
7292 if (symbol
.GetType()) {
7293 // type came from explicit type-spec
7295 ApplyImplicitRules(symbol
);
7297 // Odd rules in F'2023 19.4 paras 6 & 8.
7298 Symbol
&prevRoot
{prev
->GetUltimate()};
7299 if (const auto *type
{prevRoot
.GetType()}) {
7300 symbol
.SetType(*type
);
7302 ApplyImplicitRules(symbol
);
7304 if (prevRoot
.has
<ObjectEntityDetails
>() ||
7305 ConvertToObjectEntity(prevRoot
)) {
7306 if (prevRoot
.IsObjectArray() &&
7307 context().ShouldWarn(
7308 common::LanguageFeature::OddIndexVariableRestrictions
)) {
7309 SayWithDecl(name
, *prev
,
7310 "Index variable '%s' should be scalar in the enclosing scope"_port_en_US
)
7311 .set_languageFeature(
7312 common::LanguageFeature::OddIndexVariableRestrictions
);
7314 } else if (!prevRoot
.has
<CommonBlockDetails
>() &&
7315 context().ShouldWarn(
7316 common::LanguageFeature::OddIndexVariableRestrictions
)) {
7317 SayWithDecl(name
, *prev
,
7318 "Index variable '%s' should be a scalar object or common block if it is present in the enclosing scope"_port_en_US
)
7319 .set_languageFeature(
7320 common::LanguageFeature::OddIndexVariableRestrictions
);
7323 EvaluateExpr(parser::Scalar
{parser::Integer
{common::Clone(name
)}});
7326 // We need to make sure that all of the index-names get declared before the
7327 // expressions in the loop control are evaluated so that references to the
7328 // index-names in the expressions are correctly detected.
7329 bool ConstructVisitor::Pre(const parser::ConcurrentHeader
&header
) {
7330 BeginDeclTypeSpec();
7331 Walk(std::get
<std::optional
<parser::IntegerTypeSpec
>>(header
.t
));
7332 const auto &controls
{
7333 std::get
<std::list
<parser::ConcurrentControl
>>(header
.t
)};
7334 for (const auto &control
: controls
) {
7335 ResolveIndexName(control
);
7338 Walk(std::get
<std::optional
<parser::ScalarLogicalExpr
>>(header
.t
));
7343 bool ConstructVisitor::Pre(const parser::LocalitySpec::Local
&x
) {
7344 for (auto &name
: x
.v
) {
7345 DeclareLocalEntity(name
, Symbol::Flag::LocalityLocal
);
7350 bool ConstructVisitor::Pre(const parser::LocalitySpec::LocalInit
&x
) {
7351 for (auto &name
: x
.v
) {
7352 DeclareLocalEntity(name
, Symbol::Flag::LocalityLocalInit
);
7357 bool ConstructVisitor::Pre(const parser::LocalitySpec::Reduce
&x
) {
7358 for (const auto &name
: std::get
<std::list
<parser::Name
>>(x
.t
)) {
7359 DeclareLocalEntity(name
, Symbol::Flag::LocalityReduce
);
7364 bool ConstructVisitor::Pre(const parser::LocalitySpec::Shared
&x
) {
7365 for (const auto &name
: x
.v
) {
7366 if (!FindSymbol(name
)) {
7367 context().Warn(common::UsageWarning::ImplicitShared
, name
.source
,
7368 "Variable '%s' with SHARED locality implicitly declared"_warn_en_US
,
7371 Symbol
&prev
{FindOrDeclareEnclosingEntity(name
)};
7372 if (PassesSharedLocalityChecks(name
, prev
)) {
7373 MakeHostAssocSymbol(name
, prev
).set(Symbol::Flag::LocalityShared
);
7379 bool ConstructVisitor::Pre(const parser::AcSpec
&x
) {
7380 ProcessTypeSpec(x
.type
);
7385 // Section 19.4, paragraph 5 says that each ac-do-variable has the scope of the
7386 // enclosing ac-implied-do
7387 bool ConstructVisitor::Pre(const parser::AcImpliedDo
&x
) {
7388 auto &values
{std::get
<std::list
<parser::AcValue
>>(x
.t
)};
7389 auto &control
{std::get
<parser::AcImpliedDoControl
>(x
.t
)};
7390 auto &type
{std::get
<std::optional
<parser::IntegerTypeSpec
>>(control
.t
)};
7391 auto &bounds
{std::get
<parser::AcImpliedDoControl::Bounds
>(control
.t
)};
7392 // F'2018 has the scope of the implied DO variable covering the entire
7393 // implied DO production (19.4(5)), which seems wrong in cases where the name
7394 // of the implied DO variable appears in one of the bound expressions. Thus
7395 // this extension, which shrinks the scope of the variable to exclude the
7396 // expressions in the bounds.
7397 auto restore
{BeginCheckOnIndexUseInOwnBounds(bounds
.name
)};
7401 EndCheckOnIndexUseInOwnBounds(restore
);
7402 PushScope(Scope::Kind::ImpliedDos
, nullptr);
7403 DeclareStatementEntity(bounds
.name
, type
);
7409 bool ConstructVisitor::Pre(const parser::DataImpliedDo
&x
) {
7410 auto &objects
{std::get
<std::list
<parser::DataIDoObject
>>(x
.t
)};
7411 auto &type
{std::get
<std::optional
<parser::IntegerTypeSpec
>>(x
.t
)};
7412 auto &bounds
{std::get
<parser::DataImpliedDo::Bounds
>(x
.t
)};
7413 // See comment in Pre(AcImpliedDo) above.
7414 auto restore
{BeginCheckOnIndexUseInOwnBounds(bounds
.name
)};
7418 EndCheckOnIndexUseInOwnBounds(restore
);
7419 bool pushScope
{currScope().kind() != Scope::Kind::ImpliedDos
};
7421 PushScope(Scope::Kind::ImpliedDos
, nullptr);
7423 DeclareStatementEntity(bounds
.name
, type
);
7431 // Sets InDataStmt flag on a variable (or misidentified function) in a DATA
7432 // statement so that the predicate IsInitialized() will be true
7433 // during semantic analysis before the symbol's initializer is constructed.
7434 bool ConstructVisitor::Pre(const parser::DataIDoObject
&x
) {
7437 [&](const parser::Scalar
<Indirection
<parser::Designator
>> &y
) {
7438 Walk(y
.thing
.value());
7439 const parser::Name
&first
{parser::GetFirstName(y
.thing
.value())};
7441 first
.symbol
->set(Symbol::Flag::InDataStmt
);
7444 [&](const Indirection
<parser::DataImpliedDo
> &y
) { Walk(y
.value()); },
7450 bool ConstructVisitor::Pre(const parser::DataStmtObject
&x
) {
7451 // Subtle: DATA statements may appear in both the specification and
7452 // execution parts, but should be treated as if in the execution part
7453 // for purposes of implicit variable declaration vs. host association.
7454 // When a name first appears as an object in a DATA statement, it should
7455 // be implicitly declared locally as if it had been assigned.
7456 auto flagRestorer
{common::ScopedSet(inSpecificationPart_
, false)};
7459 [&](const Indirection
<parser::Variable
> &y
) {
7460 auto restorer
{common::ScopedSet(deferImplicitTyping_
, true)};
7462 const parser::Name
&first
{parser::GetFirstName(y
.value())};
7464 first
.symbol
->set(Symbol::Flag::InDataStmt
);
7467 [&](const parser::DataImpliedDo
&y
) {
7468 PushScope(Scope::Kind::ImpliedDos
, nullptr);
7477 bool ConstructVisitor::Pre(const parser::DataStmtValue
&x
) {
7478 const auto &data
{std::get
<parser::DataStmtConstant
>(x
.t
)};
7479 auto &mutableData
{const_cast<parser::DataStmtConstant
&>(data
)};
7480 if (auto *elem
{parser::Unwrap
<parser::ArrayElement
>(mutableData
)}) {
7481 if (const auto *name
{std::get_if
<parser::Name
>(&elem
->base
.u
)}) {
7482 if (const Symbol
* symbol
{FindSymbol(*name
)};
7483 symbol
&& symbol
->GetUltimate().has
<DerivedTypeDetails
>()) {
7484 mutableData
.u
= elem
->ConvertToStructureConstructor(
7485 DerivedTypeSpec
{name
->source
, *symbol
});
7492 bool ConstructVisitor::Pre(const parser::DoConstruct
&x
) {
7493 if (x
.IsDoConcurrent()) {
7494 // The new scope has Kind::Forall for index variable name conflict
7495 // detection with nested FORALL/DO CONCURRENT constructs in
7496 // ResolveIndexName().
7497 PushScope(Scope::Kind::Forall
, nullptr);
7501 void ConstructVisitor::Post(const parser::DoConstruct
&x
) {
7502 if (x
.IsDoConcurrent()) {
7507 bool ConstructVisitor::Pre(const parser::ForallConstruct
&) {
7508 PushScope(Scope::Kind::Forall
, nullptr);
7511 void ConstructVisitor::Post(const parser::ForallConstruct
&) { PopScope(); }
7512 bool ConstructVisitor::Pre(const parser::ForallStmt
&) {
7513 PushScope(Scope::Kind::Forall
, nullptr);
7516 void ConstructVisitor::Post(const parser::ForallStmt
&) { PopScope(); }
7518 bool ConstructVisitor::Pre(const parser::BlockConstruct
&x
) {
7519 const auto &[blockStmt
, specPart
, execPart
, endBlockStmt
] = x
.t
;
7521 CheckDef(blockStmt
.statement
.v
);
7522 PushScope(Scope::Kind::BlockConstruct
, nullptr);
7524 HandleImpliedAsynchronousInScope(execPart
);
7528 CheckRef(endBlockStmt
.statement
.v
);
7532 void ConstructVisitor::Post(const parser::Selector
&x
) {
7533 GetCurrentAssociation().selector
= ResolveSelector(x
);
7536 void ConstructVisitor::Post(const parser::AssociateStmt
&x
) {
7538 PushScope(Scope::Kind::OtherConstruct
, nullptr);
7539 const auto assocCount
{std::get
<std::list
<parser::Association
>>(x
.t
).size()};
7540 for (auto nthLastAssoc
{assocCount
}; nthLastAssoc
> 0; --nthLastAssoc
) {
7541 SetCurrentAssociation(nthLastAssoc
);
7542 if (auto *symbol
{MakeAssocEntity()}) {
7543 const MaybeExpr
&expr
{GetCurrentAssociation().selector
.expr
};
7544 if (ExtractCoarrayRef(expr
)) { // C1103
7545 Say("Selector must not be a coindexed object"_err_en_US
);
7547 if (evaluate::IsAssumedRank(expr
)) {
7548 Say("Selector must not be assumed-rank"_err_en_US
);
7550 SetTypeFromAssociation(*symbol
);
7551 SetAttrsFromAssociation(*symbol
);
7554 PopAssociation(assocCount
);
7557 void ConstructVisitor::Post(const parser::EndAssociateStmt
&x
) {
7562 bool ConstructVisitor::Pre(const parser::Association
&x
) {
7564 const auto &name
{std::get
<parser::Name
>(x
.t
)};
7565 GetCurrentAssociation().name
= &name
;
7569 bool ConstructVisitor::Pre(const parser::ChangeTeamStmt
&x
) {
7571 PushScope(Scope::Kind::OtherConstruct
, nullptr);
7576 void ConstructVisitor::Post(const parser::CoarrayAssociation
&x
) {
7577 const auto &decl
{std::get
<parser::CodimensionDecl
>(x
.t
)};
7578 const auto &name
{std::get
<parser::Name
>(decl
.t
)};
7579 if (auto *symbol
{FindInScope(name
)}) {
7580 const auto &selector
{std::get
<parser::Selector
>(x
.t
)};
7581 if (auto sel
{ResolveSelector(selector
)}) {
7582 const Symbol
*whole
{UnwrapWholeSymbolDataRef(sel
.expr
)};
7583 if (!whole
|| whole
->Corank() == 0) {
7584 Say(sel
.source
, // C1116
7585 "Selector in coarray association must name a coarray"_err_en_US
);
7586 } else if (auto dynType
{sel
.expr
->GetType()}) {
7587 if (!symbol
->GetType()) {
7588 symbol
->SetType(ToDeclTypeSpec(std::move(*dynType
)));
7595 void ConstructVisitor::Post(const parser::EndChangeTeamStmt
&x
) {
7601 bool ConstructVisitor::Pre(const parser::SelectTypeConstruct
&) {
7606 void ConstructVisitor::Post(const parser::SelectTypeConstruct
&) {
7610 void ConstructVisitor::Post(const parser::SelectTypeStmt
&x
) {
7611 auto &association
{GetCurrentAssociation()};
7612 if (const std::optional
<parser::Name
> &name
{std::get
<1>(x
.t
)}) {
7613 // This isn't a name in the current scope, it is in each TypeGuardStmt
7614 MakePlaceholder(*name
, MiscDetails::Kind::SelectTypeAssociateName
);
7615 association
.name
= &*name
;
7616 if (ExtractCoarrayRef(association
.selector
.expr
)) { // C1103
7617 Say("Selector must not be a coindexed object"_err_en_US
);
7619 if (association
.selector
.expr
) {
7620 auto exprType
{association
.selector
.expr
->GetType()};
7621 if (exprType
&& !exprType
->IsPolymorphic()) { // C1159
7622 Say(association
.selector
.source
,
7623 "Selector '%s' in SELECT TYPE statement must be "
7624 "polymorphic"_err_en_US
);
7629 whole
{UnwrapWholeSymbolDataRef(association
.selector
.expr
)}) {
7630 ConvertToObjectEntity(const_cast<Symbol
&>(*whole
));
7631 if (!IsVariableName(*whole
)) {
7632 Say(association
.selector
.source
, // C901
7633 "Selector is not a variable"_err_en_US
);
7636 if (const DeclTypeSpec
* type
{whole
->GetType()}) {
7637 if (!type
->IsPolymorphic()) { // C1159
7638 Say(association
.selector
.source
,
7639 "Selector '%s' in SELECT TYPE statement must be "
7640 "polymorphic"_err_en_US
);
7644 Say(association
.selector
.source
, // C1157
7645 "Selector is not a named variable: 'associate-name =>' is required"_err_en_US
);
7651 void ConstructVisitor::Post(const parser::SelectRankStmt
&x
) {
7652 auto &association
{GetCurrentAssociation()};
7653 if (const std::optional
<parser::Name
> &name
{std::get
<1>(x
.t
)}) {
7654 // This isn't a name in the current scope, it is in each SelectRankCaseStmt
7655 MakePlaceholder(*name
, MiscDetails::Kind::SelectRankAssociateName
);
7656 association
.name
= &*name
;
7660 bool ConstructVisitor::Pre(const parser::SelectTypeConstruct::TypeCase
&) {
7661 PushScope(Scope::Kind::OtherConstruct
, nullptr);
7664 void ConstructVisitor::Post(const parser::SelectTypeConstruct::TypeCase
&) {
7668 bool ConstructVisitor::Pre(const parser::SelectRankConstruct::RankCase
&) {
7669 PushScope(Scope::Kind::OtherConstruct
, nullptr);
7672 void ConstructVisitor::Post(const parser::SelectRankConstruct::RankCase
&) {
7676 bool ConstructVisitor::Pre(const parser::TypeGuardStmt::Guard
&x
) {
7677 if (std::holds_alternative
<parser::DerivedTypeSpec
>(x
.u
)) {
7679 SetDeclTypeSpecCategory(DeclTypeSpec::Category::ClassDerived
);
7684 void ConstructVisitor::Post(const parser::TypeGuardStmt::Guard
&x
) {
7685 if (auto *symbol
{MakeAssocEntity()}) {
7686 if (std::holds_alternative
<parser::Default
>(x
.u
)) {
7687 SetTypeFromAssociation(*symbol
);
7688 } else if (const auto *type
{GetDeclTypeSpec()}) {
7689 symbol
->SetType(*type
);
7691 SetAttrsFromAssociation(*symbol
);
7695 void ConstructVisitor::Post(const parser::SelectRankCaseStmt::Rank
&x
) {
7696 if (auto *symbol
{MakeAssocEntity()}) {
7697 SetTypeFromAssociation(*symbol
);
7698 auto &details
{symbol
->get
<AssocEntityDetails
>()};
7699 // Don't call SetAttrsFromAssociation() for SELECT RANK.
7700 Attrs selectorAttrs
{
7701 evaluate::GetAttrs(GetCurrentAssociation().selector
.expr
)};
7702 Attrs attrsToKeep
{Attr::ASYNCHRONOUS
, Attr::TARGET
, Attr::VOLATILE
};
7703 if (const auto *rankValue
{
7704 std::get_if
<parser::ScalarIntConstantExpr
>(&x
.u
)}) {
7706 if (auto expr
{EvaluateIntExpr(*rankValue
)}) {
7707 if (auto val
{evaluate::ToInt64(*expr
)}) {
7708 details
.set_rank(*val
);
7709 attrsToKeep
|= Attrs
{Attr::ALLOCATABLE
, Attr::POINTER
};
7711 Say("RANK() expression must be constant"_err_en_US
);
7714 } else if (std::holds_alternative
<parser::Star
>(x
.u
)) {
7715 // RANK(*): assumed-size
7716 details
.set_IsAssumedSize();
7718 CHECK(std::holds_alternative
<parser::Default
>(x
.u
));
7719 // RANK DEFAULT: assumed-rank
7720 details
.set_IsAssumedRank();
7721 attrsToKeep
|= Attrs
{Attr::ALLOCATABLE
, Attr::POINTER
};
7723 symbol
->attrs() |= selectorAttrs
& attrsToKeep
;
7727 bool ConstructVisitor::Pre(const parser::SelectRankConstruct
&) {
7732 void ConstructVisitor::Post(const parser::SelectRankConstruct
&) {
7736 bool ConstructVisitor::CheckDef(const std::optional
<parser::Name
> &x
) {
7737 if (x
&& !x
->symbol
) {
7738 // Construct names are not scoped by BLOCK in the standard, but many,
7739 // but not all, compilers do treat them as if they were so scoped.
7740 if (Symbol
* inner
{FindInScope(currScope(), *x
)}) {
7741 SayAlreadyDeclared(*x
, *inner
);
7743 if (context().ShouldWarn(common::LanguageFeature::BenignNameClash
)) {
7745 other
{FindInScopeOrBlockConstructs(InclusiveScope(), x
->source
)}) {
7746 SayWithDecl(*x
, *other
,
7747 "The construct name '%s' should be distinct at the subprogram level"_port_en_US
)
7748 .set_languageFeature(common::LanguageFeature::BenignNameClash
);
7751 MakeSymbol(*x
, MiscDetails
{MiscDetails::Kind::ConstructName
});
7757 void ConstructVisitor::CheckRef(const std::optional
<parser::Name
> &x
) {
7759 // Just add an occurrence of this name; checking is done in ValidateLabels
7764 // Make a symbol for the associating entity of the current association.
7765 Symbol
*ConstructVisitor::MakeAssocEntity() {
7766 Symbol
*symbol
{nullptr};
7767 auto &association
{GetCurrentAssociation()};
7768 if (association
.name
) {
7769 symbol
= &MakeSymbol(*association
.name
, UnknownDetails
{});
7770 if (symbol
->has
<AssocEntityDetails
>() && symbol
->owner() == currScope()) {
7771 Say(*association
.name
, // C1102
7772 "The associate name '%s' is already used in this associate statement"_err_en_US
);
7775 } else if (const Symbol
*
7776 whole
{UnwrapWholeSymbolDataRef(association
.selector
.expr
)}) {
7777 symbol
= &MakeSymbol(whole
->name());
7781 if (auto &expr
{association
.selector
.expr
}) {
7782 symbol
->set_details(AssocEntityDetails
{common::Clone(*expr
)});
7784 symbol
->set_details(AssocEntityDetails
{});
7789 // Set the type of symbol based on the current association selector.
7790 void ConstructVisitor::SetTypeFromAssociation(Symbol
&symbol
) {
7791 auto &details
{symbol
.get
<AssocEntityDetails
>()};
7792 const MaybeExpr
*pexpr
{&details
.expr()};
7794 pexpr
= &GetCurrentAssociation().selector
.expr
;
7797 const SomeExpr
&expr
{**pexpr
};
7798 if (std::optional
<evaluate::DynamicType
> type
{expr
.GetType()}) {
7799 if (const auto *charExpr
{
7800 evaluate::UnwrapExpr
<evaluate::Expr
<evaluate::SomeCharacter
>>(
7802 symbol
.SetType(ToDeclTypeSpec(std::move(*type
),
7803 FoldExpr(common::visit(
7804 [](const auto &kindChar
) { return kindChar
.LEN(); },
7807 symbol
.SetType(ToDeclTypeSpec(std::move(*type
)));
7810 // BOZ literals, procedure designators, &c. are not acceptable
7811 Say(symbol
.name(), "Associate name '%s' must have a type"_err_en_US
);
7816 // If current selector is a variable, set some of its attributes on symbol.
7817 // For ASSOCIATE, CHANGE TEAM, and SELECT TYPE only; not SELECT RANK.
7818 void ConstructVisitor::SetAttrsFromAssociation(Symbol
&symbol
) {
7819 Attrs attrs
{evaluate::GetAttrs(GetCurrentAssociation().selector
.expr
)};
7821 attrs
& Attrs
{Attr::TARGET
, Attr::ASYNCHRONOUS
, Attr::VOLATILE
};
7822 if (attrs
.test(Attr::POINTER
)) {
7823 SetImplicitAttr(symbol
, Attr::TARGET
);
7827 ConstructVisitor::Selector
ConstructVisitor::ResolveSelector(
7828 const parser::Selector
&x
) {
7829 return common::visit(common::visitors
{
7830 [&](const parser::Expr
&expr
) {
7831 return Selector
{expr
.source
, EvaluateExpr(x
)};
7833 [&](const parser::Variable
&var
) {
7834 return Selector
{var
.GetSource(), EvaluateExpr(x
)};
7840 // Set the current association to the nth to the last association on the
7841 // association stack. The top of the stack is at n = 1. This allows access
7842 // to the interior of a list of associations at the top of the stack.
7843 void ConstructVisitor::SetCurrentAssociation(std::size_t n
) {
7844 CHECK(n
> 0 && n
<= associationStack_
.size());
7845 currentAssociation_
= &associationStack_
[associationStack_
.size() - n
];
7848 ConstructVisitor::Association
&ConstructVisitor::GetCurrentAssociation() {
7849 CHECK(currentAssociation_
);
7850 return *currentAssociation_
;
7853 void ConstructVisitor::PushAssociation() {
7854 associationStack_
.emplace_back(Association
{});
7855 currentAssociation_
= &associationStack_
.back();
7858 void ConstructVisitor::PopAssociation(std::size_t count
) {
7859 CHECK(count
> 0 && count
<= associationStack_
.size());
7860 associationStack_
.resize(associationStack_
.size() - count
);
7861 currentAssociation_
=
7862 associationStack_
.empty() ? nullptr : &associationStack_
.back();
7865 const DeclTypeSpec
&ConstructVisitor::ToDeclTypeSpec(
7866 evaluate::DynamicType
&&type
) {
7867 switch (type
.category()) {
7868 SWITCH_COVERS_ALL_CASES
7869 case common::TypeCategory::Integer
:
7870 case common::TypeCategory::Unsigned
:
7871 case common::TypeCategory::Real
:
7872 case common::TypeCategory::Complex
:
7873 return context().MakeNumericType(type
.category(), type
.kind());
7874 case common::TypeCategory::Logical
:
7875 return context().MakeLogicalType(type
.kind());
7876 case common::TypeCategory::Derived
:
7877 if (type
.IsAssumedType()) {
7878 return currScope().MakeTypeStarType();
7879 } else if (type
.IsUnlimitedPolymorphic()) {
7880 return currScope().MakeClassStarType();
7882 return currScope().MakeDerivedType(
7883 type
.IsPolymorphic() ? DeclTypeSpec::ClassDerived
7884 : DeclTypeSpec::TypeDerived
,
7885 common::Clone(type
.GetDerivedTypeSpec())
7889 case common::TypeCategory::Character
:
7894 const DeclTypeSpec
&ConstructVisitor::ToDeclTypeSpec(
7895 evaluate::DynamicType
&&type
, MaybeSubscriptIntExpr
&&length
) {
7896 CHECK(type
.category() == common::TypeCategory::Character
);
7898 return currScope().MakeCharacterType(
7899 ParamValue
{SomeIntExpr
{*std::move(length
)}, common::TypeParamAttr::Len
},
7900 KindExpr
{type
.kind()});
7902 return currScope().MakeCharacterType(
7903 ParamValue::Deferred(common::TypeParamAttr::Len
),
7904 KindExpr
{type
.kind()});
7908 class ExecutionPartSkimmerBase
{
7910 template <typename A
> bool Pre(const A
&) { return true; }
7911 template <typename A
> void Post(const A
&) {}
7913 bool InNestedBlockConstruct() const { return blockDepth_
> 0; }
7915 bool Pre(const parser::AssociateConstruct
&) {
7919 void Post(const parser::AssociateConstruct
&) { PopScope(); }
7920 bool Pre(const parser::Association
&x
) {
7921 Hide(std::get
<parser::Name
>(x
.t
));
7924 bool Pre(const parser::BlockConstruct
&) {
7929 void Post(const parser::BlockConstruct
&) {
7933 // Note declarations of local names in BLOCK constructs.
7934 // Don't have to worry about INTENT(), VALUE, or OPTIONAL
7935 // (pertinent only to dummy arguments), ASYNCHRONOUS/VOLATILE,
7936 // or accessibility attributes,
7937 bool Pre(const parser::EntityDecl
&x
) {
7938 Hide(std::get
<parser::ObjectName
>(x
.t
));
7941 bool Pre(const parser::ObjectDecl
&x
) {
7942 Hide(std::get
<parser::ObjectName
>(x
.t
));
7945 bool Pre(const parser::PointerDecl
&x
) {
7946 Hide(std::get
<parser::Name
>(x
.t
));
7949 bool Pre(const parser::BindEntity
&x
) {
7950 Hide(std::get
<parser::Name
>(x
.t
));
7953 bool Pre(const parser::ContiguousStmt
&x
) {
7954 for (const parser::Name
&name
: x
.v
) {
7959 bool Pre(const parser::DimensionStmt::Declaration
&x
) {
7960 Hide(std::get
<parser::Name
>(x
.t
));
7963 bool Pre(const parser::ExternalStmt
&x
) {
7964 for (const parser::Name
&name
: x
.v
) {
7969 bool Pre(const parser::IntrinsicStmt
&x
) {
7970 for (const parser::Name
&name
: x
.v
) {
7975 bool Pre(const parser::CodimensionStmt
&x
) {
7976 for (const parser::CodimensionDecl
&decl
: x
.v
) {
7977 Hide(std::get
<parser::Name
>(decl
.t
));
7981 void Post(const parser::ImportStmt
&x
) {
7982 if (x
.kind
== common::ImportKind::None
||
7983 x
.kind
== common::ImportKind::Only
) {
7984 if (!nestedScopes_
.front().importOnly
.has_value()) {
7985 nestedScopes_
.front().importOnly
.emplace();
7987 for (const auto &name
: x
.names
) {
7988 nestedScopes_
.front().importOnly
->emplace(name
.source
);
7991 // no special handling needed for explicit names or IMPORT, ALL
7994 void Post(const parser::UseStmt
&x
) {
7995 if (const auto *onlyList
{std::get_if
<std::list
<parser::Only
>>(&x
.u
)}) {
7996 for (const auto &only
: *onlyList
) {
7997 if (const auto *name
{std::get_if
<parser::Name
>(&only
.u
)}) {
7999 } else if (const auto *rename
{std::get_if
<parser::Rename
>(&only
.u
)}) {
8000 if (const auto *names
{
8001 std::get_if
<parser::Rename::Names
>(&rename
->u
)}) {
8002 Hide(std::get
<0>(names
->t
));
8007 // USE may or may not shadow symbols in host scopes
8008 nestedScopes_
.front().hasUseWithoutOnly
= true;
8011 bool Pre(const parser::DerivedTypeStmt
&x
) {
8012 Hide(std::get
<parser::Name
>(x
.t
));
8016 void Post(const parser::DerivedTypeDef
&) { PopScope(); }
8017 bool Pre(const parser::SelectTypeConstruct
&) {
8021 void Post(const parser::SelectTypeConstruct
&) { PopScope(); }
8022 bool Pre(const parser::SelectTypeStmt
&x
) {
8023 if (const auto &maybeName
{std::get
<1>(x
.t
)}) {
8028 bool Pre(const parser::SelectRankConstruct
&) {
8032 void Post(const parser::SelectRankConstruct
&) { PopScope(); }
8033 bool Pre(const parser::SelectRankStmt
&x
) {
8034 if (const auto &maybeName
{std::get
<1>(x
.t
)}) {
8040 // Iterator-modifiers contain variable declarations, and do introduce
8041 // a new scope. These variables can only have integer types, and their
8042 // scope only extends until the end of the clause. A potential alternative
8043 // to the code below may be to ignore OpenMP clauses, but it's not clear
8044 // if OMP-specific checks can be avoided altogether.
8045 bool Pre(const parser::OmpClause
&x
) {
8046 if (OmpVisitor::NeedsScope(x
)) {
8051 void Post(const parser::OmpClause
&x
) {
8052 if (OmpVisitor::NeedsScope(x
)) {
8058 bool IsHidden(SourceName name
) {
8059 for (const auto &scope
: nestedScopes_
) {
8060 if (scope
.locals
.find(name
) != scope
.locals
.end()) {
8061 return true; // shadowed by nested declaration
8063 if (scope
.hasUseWithoutOnly
) {
8066 if (scope
.importOnly
&&
8067 scope
.importOnly
->find(name
) == scope
.importOnly
->end()) {
8068 return true; // not imported
8074 void EndWalk() { CHECK(nestedScopes_
.empty()); }
8077 void PushScope() { nestedScopes_
.emplace_front(); }
8078 void PopScope() { nestedScopes_
.pop_front(); }
8079 void Hide(const parser::Name
&name
) {
8080 nestedScopes_
.front().locals
.emplace(name
.source
);
8084 struct NestedScopeInfo
{
8085 bool hasUseWithoutOnly
{false};
8086 std::set
<SourceName
> locals
;
8087 std::optional
<std::set
<SourceName
>> importOnly
;
8089 std::list
<NestedScopeInfo
> nestedScopes_
;
8092 class ExecutionPartAsyncIOSkimmer
: public ExecutionPartSkimmerBase
{
8094 explicit ExecutionPartAsyncIOSkimmer(SemanticsContext
&context
)
8095 : context_
{context
} {}
8097 void Walk(const parser::Block
&block
) {
8098 parser::Walk(block
, *this);
8102 const std::set
<SourceName
> asyncIONames() const { return asyncIONames_
; }
8104 using ExecutionPartSkimmerBase::Post
;
8105 using ExecutionPartSkimmerBase::Pre
;
8107 bool Pre(const parser::IoControlSpec::Asynchronous
&async
) {
8108 if (auto folded
{evaluate::Fold(
8109 context_
.foldingContext(), AnalyzeExpr(context_
, async
.v
))}) {
8111 evaluate::GetScalarConstantValue
<evaluate::Ascii
>(*folded
)}) {
8112 for (char ch
: *str
) {
8114 inAsyncIO_
= ch
== 'y' || ch
== 'Y';
8122 void Post(const parser::ReadStmt
&) { inAsyncIO_
= false; }
8123 void Post(const parser::WriteStmt
&) { inAsyncIO_
= false; }
8124 void Post(const parser::IoControlSpec::Size
&size
) {
8125 if (const auto *designator
{
8126 std::get_if
<common::Indirection
<parser::Designator
>>(
8127 &size
.v
.thing
.thing
.u
)}) {
8128 NoteAsyncIODesignator(designator
->value());
8131 void Post(const parser::InputItem
&x
) {
8132 if (const auto *var
{std::get_if
<parser::Variable
>(&x
.u
)}) {
8133 if (const auto *designator
{
8134 std::get_if
<common::Indirection
<parser::Designator
>>(&var
->u
)}) {
8135 NoteAsyncIODesignator(designator
->value());
8139 void Post(const parser::OutputItem
&x
) {
8140 if (const auto *expr
{std::get_if
<parser::Expr
>(&x
.u
)}) {
8141 if (const auto *designator
{
8142 std::get_if
<common::Indirection
<parser::Designator
>>(&expr
->u
)}) {
8143 NoteAsyncIODesignator(designator
->value());
8149 void NoteAsyncIODesignator(const parser::Designator
&designator
) {
8150 if (inAsyncIO_
&& !InNestedBlockConstruct()) {
8151 const parser::Name
&name
{parser::GetFirstName(designator
)};
8152 if (!IsHidden(name
.source
)) {
8153 asyncIONames_
.insert(name
.source
);
8158 SemanticsContext
&context_
;
8159 bool inAsyncIO_
{false};
8160 std::set
<SourceName
> asyncIONames_
;
8163 // Any data list item or SIZE= specifier of an I/O data transfer statement
8164 // with ASYNCHRONOUS="YES" implicitly has the ASYNCHRONOUS attribute in the
8166 void ConstructVisitor::HandleImpliedAsynchronousInScope(
8167 const parser::Block
&block
) {
8168 ExecutionPartAsyncIOSkimmer skimmer
{context()};
8169 skimmer
.Walk(block
);
8170 for (auto name
: skimmer
.asyncIONames()) {
8171 if (Symbol
* symbol
{currScope().FindSymbol(name
)}) {
8172 if (!symbol
->attrs().test(Attr::ASYNCHRONOUS
)) {
8173 if (&symbol
->owner() != &currScope()) {
8174 symbol
= &*currScope()
8175 .try_emplace(name
, HostAssocDetails
{*symbol
})
8178 if (symbol
->has
<AssocEntityDetails
>()) {
8179 symbol
= const_cast<Symbol
*>(&GetAssociationRoot(*symbol
));
8181 SetImplicitAttr(*symbol
, Attr::ASYNCHRONOUS
);
8187 // ResolveNamesVisitor implementation
8189 bool ResolveNamesVisitor::Pre(const parser::FunctionReference
&x
) {
8190 HandleCall(Symbol::Flag::Function
, x
.v
);
8193 bool ResolveNamesVisitor::Pre(const parser::CallStmt
&x
) {
8194 HandleCall(Symbol::Flag::Subroutine
, x
.call
);
8199 bool ResolveNamesVisitor::Pre(const parser::ImportStmt
&x
) {
8200 auto &scope
{currScope()};
8201 // Check C896 and C899: where IMPORT statements are allowed
8202 switch (scope
.kind()) {
8203 case Scope::Kind::Module
:
8204 if (scope
.IsModule()) {
8205 Say("IMPORT is not allowed in a module scoping unit"_err_en_US
);
8207 } else if (x
.kind
== common::ImportKind::None
) {
8208 Say("IMPORT,NONE is not allowed in a submodule scoping unit"_err_en_US
);
8212 case Scope::Kind::MainProgram
:
8213 Say("IMPORT is not allowed in a main program scoping unit"_err_en_US
);
8215 case Scope::Kind::Subprogram
:
8216 if (scope
.parent().IsGlobal()) {
8217 Say("IMPORT is not allowed in an external subprogram scoping unit"_err_en_US
);
8221 case Scope::Kind::BlockData
: // C1415 (in part)
8222 Say("IMPORT is not allowed in a BLOCK DATA subprogram"_err_en_US
);
8226 if (auto error
{scope
.SetImportKind(x
.kind
)}) {
8227 Say(std::move(*error
));
8229 for (auto &name
: x
.names
) {
8230 if (Symbol
* outer
{FindSymbol(scope
.parent(), name
)}) {
8231 scope
.add_importName(name
.source
);
8232 if (Symbol
* symbol
{FindInScope(name
)}) {
8233 if (outer
->GetUltimate() == symbol
->GetUltimate()) {
8234 context().Warn(common::LanguageFeature::BenignNameClash
, name
.source
,
8235 "The same '%s' is already present in this scope"_port_en_US
,
8239 "A distinct '%s' is already present in this scope"_err_en_US
)
8240 .Attach(symbol
->name(), "Previous declaration of '%s'"_en_US
)
8241 .Attach(outer
->name(), "Declaration of '%s' in host scope"_en_US
);
8245 Say(name
, "'%s' not found in host scope"_err_en_US
);
8248 prevImportStmt_
= currStmtSource();
8252 const parser::Name
*DeclarationVisitor::ResolveStructureComponent(
8253 const parser::StructureComponent
&x
) {
8254 return FindComponent(ResolveDataRef(x
.base
), x
.component
);
8257 const parser::Name
*DeclarationVisitor::ResolveDesignator(
8258 const parser::Designator
&x
) {
8259 return common::visit(
8261 [&](const parser::DataRef
&x
) { return ResolveDataRef(x
); },
8262 [&](const parser::Substring
&x
) {
8263 Walk(std::get
<parser::SubstringRange
>(x
.t
).t
);
8264 return ResolveDataRef(std::get
<parser::DataRef
>(x
.t
));
8270 const parser::Name
*DeclarationVisitor::ResolveDataRef(
8271 const parser::DataRef
&x
) {
8272 return common::visit(
8274 [=](const parser::Name
&y
) { return ResolveName(y
); },
8275 [=](const Indirection
<parser::StructureComponent
> &y
) {
8276 return ResolveStructureComponent(y
.value());
8278 [&](const Indirection
<parser::ArrayElement
> &y
) {
8279 Walk(y
.value().subscripts
);
8280 const parser::Name
*name
{ResolveDataRef(y
.value().base
)};
8281 if (name
&& name
->symbol
) {
8282 if (!IsProcedure(*name
->symbol
)) {
8283 ConvertToObjectEntity(*name
->symbol
);
8284 } else if (!context().HasError(*name
->symbol
)) {
8285 SayWithDecl(*name
, *name
->symbol
,
8286 "Cannot reference function '%s' as data"_err_en_US
);
8287 context().SetError(*name
->symbol
);
8292 [&](const Indirection
<parser::CoindexedNamedObject
> &y
) {
8293 Walk(y
.value().imageSelector
);
8294 return ResolveDataRef(y
.value().base
);
8300 // If implicit types are allowed, ensure name is in the symbol table.
8301 // Otherwise, report an error if it hasn't been declared.
8302 const parser::Name
*DeclarationVisitor::ResolveName(const parser::Name
&name
) {
8303 if (!FindSymbol(name
)) {
8304 if (FindAndMarkDeclareTargetSymbol(name
)) {
8309 if (CheckForHostAssociatedImplicit(name
)) {
8310 NotePossibleBadForwardRef(name
);
8313 if (Symbol
* symbol
{name
.symbol
}) {
8314 if (CheckUseError(name
)) {
8315 return nullptr; // reported an error
8317 NotePossibleBadForwardRef(name
);
8318 symbol
->set(Symbol::Flag::ImplicitOrError
, false);
8319 if (IsUplevelReference(*symbol
)) {
8320 MakeHostAssocSymbol(name
, *symbol
);
8321 } else if (IsDummy(*symbol
) ||
8322 (!symbol
->GetType() && FindCommonBlockContaining(*symbol
))) {
8323 CheckEntryDummyUse(name
.source
, symbol
);
8324 ConvertToObjectEntity(*symbol
);
8325 ApplyImplicitRules(*symbol
);
8326 } else if (const auto *tpd
{symbol
->detailsIf
<TypeParamDetails
>()};
8327 tpd
&& !tpd
->attr()) {
8329 "Type parameter '%s' was referenced before being declared"_err_en_US
,
8331 context().SetError(*symbol
);
8333 if (checkIndexUseInOwnBounds_
&&
8334 *checkIndexUseInOwnBounds_
== name
.source
&& !InModuleFile()) {
8335 context().Warn(common::LanguageFeature::ImpliedDoIndexScope
, name
.source
,
8336 "Implied DO index '%s' uses an object of the same name in its bounds expressions"_port_en_US
,
8341 if (isImplicitNoneType() && !deferImplicitTyping_
) {
8342 Say(name
, "No explicit type declared for '%s'"_err_en_US
);
8345 // Create the symbol, then ensure that it is accessible
8346 if (checkIndexUseInOwnBounds_
&& *checkIndexUseInOwnBounds_
== name
.source
) {
8348 "Implied DO index '%s' uses itself in its own bounds expressions"_err_en_US
,
8351 MakeSymbol(InclusiveScope(), name
.source
, Attrs
{});
8352 auto *symbol
{FindSymbol(name
)};
8355 "'%s' from host scoping unit is not accessible due to IMPORT"_err_en_US
);
8358 ConvertToObjectEntity(*symbol
);
8359 ApplyImplicitRules(*symbol
);
8360 NotePossibleBadForwardRef(name
);
8364 // A specification expression may refer to a symbol in the host procedure that
8365 // is implicitly typed. Because specification parts are processed before
8366 // execution parts, this may be the first time we see the symbol. It can't be a
8367 // local in the current scope (because it's in a specification expression) so
8368 // either it is implicitly declared in the host procedure or it is an error.
8369 // We create a symbol in the host assuming it is the former; if that proves to
8370 // be wrong we report an error later in CheckDeclarations().
8371 bool DeclarationVisitor::CheckForHostAssociatedImplicit(
8372 const parser::Name
&name
) {
8373 if (!inSpecificationPart_
|| inEquivalenceStmt_
) {
8377 ApplyImplicitRules(*name
.symbol
, true);
8379 if (Scope
* host
{GetHostProcedure()}; host
&& !isImplicitNoneType(*host
)) {
8380 Symbol
*hostSymbol
{nullptr};
8382 if (currScope().CanImport(name
.source
)) {
8383 hostSymbol
= &MakeSymbol(*host
, name
.source
, Attrs
{});
8384 ConvertToObjectEntity(*hostSymbol
);
8385 ApplyImplicitRules(*hostSymbol
);
8386 hostSymbol
->set(Symbol::Flag::ImplicitOrError
);
8388 } else if (name
.symbol
->test(Symbol::Flag::ImplicitOrError
)) {
8389 hostSymbol
= name
.symbol
;
8392 Symbol
&symbol
{MakeHostAssocSymbol(name
, *hostSymbol
)};
8393 if (auto *assoc
{symbol
.detailsIf
<HostAssocDetails
>()}) {
8394 if (isImplicitNoneType()) {
8395 assoc
->implicitOrExplicitTypeError
= true;
8397 assoc
->implicitOrSpecExprError
= true;
8406 bool DeclarationVisitor::IsUplevelReference(const Symbol
&symbol
) {
8407 if (symbol
.owner().IsTopLevel()) {
8410 const Scope
&symbolUnit
{GetProgramUnitContaining(symbol
)};
8411 if (symbolUnit
== GetProgramUnitContaining(currScope())) {
8414 Scope::Kind kind
{symbolUnit
.kind()};
8415 return kind
== Scope::Kind::Subprogram
|| kind
== Scope::Kind::MainProgram
;
8419 // base is a part-ref of a derived type; find the named component in its type.
8420 // Also handles intrinsic type parameter inquiries (%kind, %len) and
8421 // COMPLEX component references (%re, %im).
8422 const parser::Name
*DeclarationVisitor::FindComponent(
8423 const parser::Name
*base
, const parser::Name
&component
) {
8424 if (!base
|| !base
->symbol
) {
8427 if (auto *misc
{base
->symbol
->detailsIf
<MiscDetails
>()}) {
8428 if (component
.source
== "kind") {
8429 if (misc
->kind() == MiscDetails::Kind::ComplexPartRe
||
8430 misc
->kind() == MiscDetails::Kind::ComplexPartIm
||
8431 misc
->kind() == MiscDetails::Kind::KindParamInquiry
||
8432 misc
->kind() == MiscDetails::Kind::LenParamInquiry
) {
8433 // x%{re,im,kind,len}%kind
8434 MakePlaceholder(component
, MiscDetails::Kind::KindParamInquiry
);
8439 CheckEntryDummyUse(base
->source
, base
->symbol
);
8440 auto &symbol
{base
->symbol
->GetUltimate()};
8441 if (!symbol
.has
<AssocEntityDetails
>() && !ConvertToObjectEntity(symbol
)) {
8442 SayWithDecl(*base
, symbol
,
8443 "'%s' is not an object and may not be used as the base of a component reference or type parameter inquiry"_err_en_US
);
8446 auto *type
{symbol
.GetType()};
8448 return nullptr; // should have already reported error
8450 if (const IntrinsicTypeSpec
* intrinsic
{type
->AsIntrinsic()}) {
8451 auto category
{intrinsic
->category()};
8452 MiscDetails::Kind miscKind
{MiscDetails::Kind::None
};
8453 if (component
.source
== "kind") {
8454 miscKind
= MiscDetails::Kind::KindParamInquiry
;
8455 } else if (category
== TypeCategory::Character
) {
8456 if (component
.source
== "len") {
8457 miscKind
= MiscDetails::Kind::LenParamInquiry
;
8459 } else if (category
== TypeCategory::Complex
) {
8460 if (component
.source
== "re") {
8461 miscKind
= MiscDetails::Kind::ComplexPartRe
;
8462 } else if (component
.source
== "im") {
8463 miscKind
= MiscDetails::Kind::ComplexPartIm
;
8466 if (miscKind
!= MiscDetails::Kind::None
) {
8467 MakePlaceholder(component
, miscKind
);
8470 } else if (DerivedTypeSpec
* derived
{type
->AsDerived()}) {
8471 derived
->Instantiate(currScope()); // in case of forward referenced type
8472 if (const Scope
* scope
{derived
->scope()}) {
8473 if (Resolve(component
, scope
->FindComponent(component
.source
))) {
8474 if (auto msg
{CheckAccessibleSymbol(currScope(), *component
.symbol
)}) {
8475 context().Say(component
.source
, *msg
);
8479 SayDerivedType(component
.source
,
8480 "Component '%s' not found in derived type '%s'"_err_en_US
, *scope
);
8485 if (symbol
.test(Symbol::Flag::Implicit
)) {
8487 "'%s' is not an object of derived type; it is implicitly typed"_err_en_US
);
8490 *base
, symbol
, "'%s' is not an object of derived type"_err_en_US
);
8495 bool DeclarationVisitor::FindAndMarkDeclareTargetSymbol(
8496 const parser::Name
&name
) {
8497 if (!specPartState_
.declareTargetNames
.empty()) {
8498 if (specPartState_
.declareTargetNames
.count(name
.source
)) {
8499 if (!currScope().IsTopLevel()) {
8500 // Search preceding scopes until we find a matching symbol or run out
8501 // of scopes to search, we skip the current scope as it's already been
8502 // designated as implicit here.
8503 for (auto *scope
= &currScope().parent();; scope
= &scope
->parent()) {
8504 if (Symbol
* symbol
{scope
->FindSymbol(name
.source
)}) {
8505 if (symbol
->test(Symbol::Flag::Subroutine
) ||
8506 symbol
->test(Symbol::Flag::Function
)) {
8507 const auto [sym
, success
]{currScope().try_emplace(
8508 symbol
->name(), Attrs
{}, HostAssocDetails
{*symbol
})};
8510 "FindAndMarkDeclareTargetSymbol could not emplace new "
8511 "subroutine/function symbol");
8512 name
.symbol
= &*sym
->second
;
8513 symbol
->test(Symbol::Flag::Subroutine
)
8514 ? name
.symbol
->set(Symbol::Flag::Subroutine
)
8515 : name
.symbol
->set(Symbol::Flag::Function
);
8518 // if we find a symbol that is not a function or subroutine, we
8519 // currently escape without doing anything.
8523 // This is our loop exit condition, as parent() has an inbuilt assert
8524 // if you call it on a top level scope, rather than returning a null
8526 if (scope
->IsTopLevel()) {
8536 void DeclarationVisitor::Initialization(const parser::Name
&name
,
8537 const parser::Initialization
&init
, bool inComponentDecl
) {
8538 // Traversal of the initializer was deferred to here so that the
8539 // symbol being declared can be available for use in the expression, e.g.:
8540 // real, parameter :: x = tiny(x)
8544 Symbol
&ultimate
{name
.symbol
->GetUltimate()};
8545 // TODO: check C762 - all bounds and type parameters of component
8546 // are colons or constant expressions if component is initialized
8549 [&](const parser::ConstantExpr
&expr
) {
8551 if (IsNamedConstant(ultimate
) || inComponentDecl
) {
8552 NonPointerInitialization(name
, expr
);
8554 // Defer analysis so forward references to nested subprograms
8555 // can be properly resolved when they appear in structure
8557 ultimate
.set(Symbol::Flag::InDataStmt
);
8560 [&](const parser::NullInit
&null
) { // => NULL()
8562 if (auto nullInit
{EvaluateExpr(null
)}) {
8563 if (!evaluate::IsNullPointer(*nullInit
)) { // C813
8564 Say(null
.v
.value().source
,
8565 "Pointer initializer must be intrinsic NULL()"_err_en_US
);
8566 } else if (IsPointer(ultimate
)) {
8567 if (auto *object
{ultimate
.detailsIf
<ObjectEntityDetails
>()}) {
8568 CHECK(!object
->init());
8569 object
->set_init(std::move(*nullInit
));
8570 } else if (auto *procPtr
{
8571 ultimate
.detailsIf
<ProcEntityDetails
>()}) {
8572 CHECK(!procPtr
->init());
8573 procPtr
->set_init(nullptr);
8577 "Non-pointer component '%s' initialized with null pointer"_err_en_US
);
8581 [&](const parser::InitialDataTarget
&target
) {
8582 // Defer analysis to the end of the specification part
8583 // so that forward references and attribute checks like SAVE
8585 auto restorer
{common::ScopedSet(deferImplicitTyping_
, true)};
8587 ultimate
.set(Symbol::Flag::InDataStmt
);
8589 [&](const std::list
<Indirection
<parser::DataStmtValue
>> &values
) {
8590 // Handled later in data-to-inits conversion
8591 ultimate
.set(Symbol::Flag::InDataStmt
);
8598 void DeclarationVisitor::PointerInitialization(
8599 const parser::Name
&name
, const parser::InitialDataTarget
&target
) {
8601 Symbol
&ultimate
{name
.symbol
->GetUltimate()};
8602 if (!context().HasError(ultimate
)) {
8603 if (IsPointer(ultimate
)) {
8605 if (MaybeExpr expr
{EvaluateExpr(target
)}) {
8606 // Validation is done in declaration checking.
8607 if (auto *details
{ultimate
.detailsIf
<ObjectEntityDetails
>()}) {
8608 CHECK(!details
->init());
8609 details
->set_init(std::move(*expr
));
8610 ultimate
.set(Symbol::Flag::InDataStmt
, false);
8611 } else if (auto *details
{ultimate
.detailsIf
<ProcEntityDetails
>()}) {
8612 // something like "REAL, EXTERNAL, POINTER :: p => t"
8613 if (evaluate::IsNullProcedurePointer(*expr
)) {
8614 CHECK(!details
->init());
8615 details
->set_init(nullptr);
8616 } else if (const Symbol
*
8617 targetSymbol
{evaluate::UnwrapWholeSymbolDataRef(*expr
)}) {
8618 CHECK(!details
->init());
8619 details
->set_init(*targetSymbol
);
8622 "Procedure pointer '%s' must be initialized with a procedure name or NULL()"_err_en_US
);
8623 context().SetError(ultimate
);
8629 "'%s' is not a pointer but is initialized like one"_err_en_US
);
8630 context().SetError(ultimate
);
8635 void DeclarationVisitor::PointerInitialization(
8636 const parser::Name
&name
, const parser::ProcPointerInit
&target
) {
8638 Symbol
&ultimate
{name
.symbol
->GetUltimate()};
8639 if (!context().HasError(ultimate
)) {
8640 if (IsProcedurePointer(ultimate
)) {
8641 auto &details
{ultimate
.get
<ProcEntityDetails
>()};
8642 if (details
.init()) {
8643 Say(name
, "'%s' was previously initialized"_err_en_US
);
8644 context().SetError(ultimate
);
8645 } else if (const auto *targetName
{
8646 std::get_if
<parser::Name
>(&target
.u
)}) {
8648 if (!CheckUseError(*targetName
) && targetName
->symbol
) {
8649 // Validation is done in declaration checking.
8650 details
.set_init(*targetName
->symbol
);
8652 } else { // explicit NULL
8653 details
.set_init(nullptr);
8657 "'%s' is not a procedure pointer but is initialized like one"_err_en_US
);
8658 context().SetError(ultimate
);
8664 void DeclarationVisitor::NonPointerInitialization(
8665 const parser::Name
&name
, const parser::ConstantExpr
&expr
) {
8666 if (!context().HasError(name
.symbol
)) {
8667 Symbol
&ultimate
{name
.symbol
->GetUltimate()};
8668 if (!context().HasError(ultimate
)) {
8669 if (IsPointer(ultimate
)) {
8671 "'%s' is a pointer but is not initialized like one"_err_en_US
);
8672 } else if (auto *details
{ultimate
.detailsIf
<ObjectEntityDetails
>()}) {
8673 if (details
->init()) {
8674 SayWithDecl(name
, *name
.symbol
,
8675 "'%s' has already been initialized"_err_en_US
);
8676 } else if (IsAllocatable(ultimate
)) {
8677 Say(name
, "Allocatable object '%s' cannot be initialized"_err_en_US
);
8678 } else if (ultimate
.owner().IsParameterizedDerivedType()) {
8679 // Save the expression for per-instantiation analysis.
8680 details
->set_unanalyzedPDTComponentInit(&expr
.thing
.value());
8681 } else if (MaybeExpr folded
{EvaluateNonPointerInitializer(
8682 ultimate
, expr
, expr
.thing
.value().source
)}) {
8683 details
->set_init(std::move(*folded
));
8684 ultimate
.set(Symbol::Flag::InDataStmt
, false);
8687 Say(name
, "'%s' is not an object that can be initialized"_err_en_US
);
8693 void ResolveNamesVisitor::HandleCall(
8694 Symbol::Flag procFlag
, const parser::Call
&call
) {
8697 [&](const parser::Name
&x
) { HandleProcedureName(procFlag
, x
); },
8698 [&](const parser::ProcComponentRef
&x
) {
8700 const parser::Name
&name
{x
.v
.thing
.component
};
8701 if (Symbol
* symbol
{name
.symbol
}) {
8702 if (IsProcedure(*symbol
)) {
8703 SetProcFlag(name
, *symbol
, procFlag
);
8708 std::get
<parser::ProcedureDesignator
>(call
.t
).u
);
8709 const auto &arguments
{std::get
<std::list
<parser::ActualArgSpec
>>(call
.t
)};
8711 // Once an object has appeared in a specification function reference as
8712 // a whole scalar actual argument, it cannot be (re)dimensioned later.
8713 // The fact that it appeared to be a scalar may determine the resolution
8714 // or the result of an inquiry intrinsic function or generic procedure.
8715 if (inSpecificationPart_
) {
8716 for (const auto &argSpec
: arguments
) {
8717 const auto &actual
{std::get
<parser::ActualArg
>(argSpec
.t
)};
8718 if (const auto *expr
{
8719 std::get_if
<common::Indirection
<parser::Expr
>>(&actual
.u
)}) {
8720 if (const auto *designator
{
8721 std::get_if
<common::Indirection
<parser::Designator
>>(
8722 &expr
->value().u
)}) {
8723 if (const auto *dataRef
{
8724 std::get_if
<parser::DataRef
>(&designator
->value().u
)}) {
8725 if (const auto *name
{std::get_if
<parser::Name
>(&dataRef
->u
)};
8726 name
&& name
->symbol
) {
8727 const Symbol
&symbol
{*name
->symbol
};
8728 const auto *object
{symbol
.detailsIf
<ObjectEntityDetails
>()};
8729 if (symbol
.has
<EntityDetails
>() ||
8730 (object
&& !object
->IsArray())) {
8731 NoteScalarSpecificationArgument(symbol
);
8741 void ResolveNamesVisitor::HandleProcedureName(
8742 Symbol::Flag flag
, const parser::Name
&name
) {
8743 CHECK(flag
== Symbol::Flag::Function
|| flag
== Symbol::Flag::Subroutine
);
8744 auto *symbol
{FindSymbol(NonDerivedTypeScope(), name
)};
8746 if (IsIntrinsic(name
.source
, flag
)) {
8747 symbol
= &MakeSymbol(InclusiveScope(), name
.source
, Attrs
{});
8748 SetImplicitAttr(*symbol
, Attr::INTRINSIC
);
8749 } else if (const auto ppcBuiltinScope
=
8750 currScope().context().GetPPCBuiltinsScope()) {
8751 // Check if it is a builtin from the predefined module
8752 symbol
= FindSymbol(*ppcBuiltinScope
, name
);
8754 symbol
= &MakeSymbol(context().globalScope(), name
.source
, Attrs
{});
8757 symbol
= &MakeSymbol(context().globalScope(), name
.source
, Attrs
{});
8759 Resolve(name
, *symbol
);
8760 ConvertToProcEntity(*symbol
, name
.source
);
8761 if (!symbol
->attrs().test(Attr::INTRINSIC
)) {
8762 if (CheckImplicitNoneExternal(name
.source
, *symbol
)) {
8763 MakeExternal(*symbol
);
8764 // Create a place-holder HostAssocDetails symbol to preclude later
8765 // use of this name as a local symbol; but don't actually use this new
8766 // HostAssocDetails symbol in expressions.
8767 MakeHostAssocSymbol(name
, *symbol
);
8768 name
.symbol
= symbol
;
8771 CheckEntryDummyUse(name
.source
, symbol
);
8772 SetProcFlag(name
, *symbol
, flag
);
8773 } else if (CheckUseError(name
)) {
8774 // error was reported
8776 symbol
= &symbol
->GetUltimate();
8778 (name
.symbol
->has
<HostAssocDetails
>() && symbol
->owner().IsGlobal() &&
8779 (symbol
->has
<ProcEntityDetails
>() ||
8780 (symbol
->has
<SubprogramDetails
>() &&
8781 symbol
->scope() /*not ENTRY*/)))) {
8782 name
.symbol
= symbol
;
8784 CheckEntryDummyUse(name
.source
, symbol
);
8785 bool convertedToProcEntity
{ConvertToProcEntity(*symbol
, name
.source
)};
8786 if (convertedToProcEntity
&& !symbol
->attrs().test(Attr::EXTERNAL
) &&
8787 IsIntrinsic(symbol
->name(), flag
) && !IsDummy(*symbol
)) {
8788 AcquireIntrinsicProcedureFlags(*symbol
);
8790 if (!SetProcFlag(name
, *symbol
, flag
)) {
8791 return; // reported error
8793 CheckImplicitNoneExternal(name
.source
, *symbol
);
8794 if (IsProcedure(*symbol
) || symbol
->has
<DerivedTypeDetails
>() ||
8795 symbol
->has
<AssocEntityDetails
>()) {
8796 // Symbols with DerivedTypeDetails and AssocEntityDetails are accepted
8797 // here as procedure-designators because this means the related
8798 // FunctionReference are mis-parsed structure constructors or array
8799 // references that will be fixed later when analyzing expressions.
8800 } else if (symbol
->has
<ObjectEntityDetails
>()) {
8801 // Symbols with ObjectEntityDetails are also accepted because this can be
8802 // a mis-parsed array reference that will be fixed later. Ensure that if
8803 // this is a symbol from a host procedure, a symbol with HostAssocDetails
8804 // is created for the current scope.
8805 // Operate on non ultimate symbol so that HostAssocDetails are also
8806 // created for symbols used associated in the host procedure.
8808 } else if (symbol
->test(Symbol::Flag::Implicit
)) {
8810 "Use of '%s' as a procedure conflicts with its implicit definition"_err_en_US
);
8812 SayWithDecl(name
, *symbol
,
8813 "Use of '%s' as a procedure conflicts with its declaration"_err_en_US
);
8818 bool ResolveNamesVisitor::CheckImplicitNoneExternal(
8819 const SourceName
&name
, const Symbol
&symbol
) {
8820 if (symbol
.has
<ProcEntityDetails
>() && isImplicitNoneExternal() &&
8821 !symbol
.attrs().test(Attr::EXTERNAL
) &&
8822 !symbol
.attrs().test(Attr::INTRINSIC
) && !symbol
.HasExplicitInterface()) {
8824 "'%s' is an external procedure without the EXTERNAL attribute in a scope with IMPLICIT NONE(EXTERNAL)"_err_en_US
);
8830 // Variant of HandleProcedureName() for use while skimming the executable
8831 // part of a subprogram to catch calls to dummy procedures that are part
8832 // of the subprogram's interface, and to mark as procedures any symbols
8833 // that might otherwise have been miscategorized as objects.
8834 void ResolveNamesVisitor::NoteExecutablePartCall(
8835 Symbol::Flag flag
, SourceName name
, bool hasCUDAChevrons
) {
8836 // Subtlety: The symbol pointers in the parse tree are not set, because
8837 // they might end up resolving elsewhere (e.g., construct entities in
8839 if (Symbol
* symbol
{currScope().FindSymbol(name
)}) {
8840 Symbol::Flag other
{flag
== Symbol::Flag::Subroutine
8841 ? Symbol::Flag::Function
8842 : Symbol::Flag::Subroutine
};
8843 if (!symbol
->test(other
)) {
8844 ConvertToProcEntity(*symbol
, name
);
8845 if (auto *details
{symbol
->detailsIf
<ProcEntityDetails
>()}) {
8847 if (IsDummy(*symbol
)) {
8848 SetImplicitAttr(*symbol
, Attr::EXTERNAL
);
8850 ApplyImplicitRules(*symbol
);
8851 if (hasCUDAChevrons
) {
8852 details
->set_isCUDAKernel();
8859 static bool IsLocallyImplicitGlobalSymbol(
8860 const Symbol
&symbol
, const parser::Name
&localName
) {
8861 if (symbol
.owner().IsGlobal()) {
8862 const auto *subp
{symbol
.detailsIf
<SubprogramDetails
>()};
8864 subp
&& subp
->entryScope() ? subp
->entryScope() : symbol
.scope()};
8865 return !(scope
&& scope
->sourceRange().Contains(localName
.source
));
8870 static bool TypesMismatchIfNonNull(
8871 const DeclTypeSpec
*type1
, const DeclTypeSpec
*type2
) {
8872 return type1
&& type2
&& *type1
!= *type2
;
8875 // Check and set the Function or Subroutine flag on symbol; false on error.
8876 bool ResolveNamesVisitor::SetProcFlag(
8877 const parser::Name
&name
, Symbol
&symbol
, Symbol::Flag flag
) {
8878 if (symbol
.test(Symbol::Flag::Function
) && flag
== Symbol::Flag::Subroutine
) {
8880 name
, symbol
, "Cannot call function '%s' like a subroutine"_err_en_US
);
8881 context().SetError(symbol
);
8883 } else if (symbol
.test(Symbol::Flag::Subroutine
) &&
8884 flag
== Symbol::Flag::Function
) {
8886 name
, symbol
, "Cannot call subroutine '%s' like a function"_err_en_US
);
8887 context().SetError(symbol
);
8889 } else if (flag
== Symbol::Flag::Function
&&
8890 IsLocallyImplicitGlobalSymbol(symbol
, name
) &&
8891 TypesMismatchIfNonNull(symbol
.GetType(), GetImplicitType(symbol
))) {
8892 SayWithDecl(name
, symbol
,
8893 "Implicit declaration of function '%s' has a different result type than in previous declaration"_err_en_US
);
8895 } else if (symbol
.has
<ProcEntityDetails
>()) {
8896 symbol
.set(flag
); // in case it hasn't been set yet
8897 if (flag
== Symbol::Flag::Function
) {
8898 ApplyImplicitRules(symbol
);
8900 if (symbol
.attrs().test(Attr::INTRINSIC
)) {
8901 AcquireIntrinsicProcedureFlags(symbol
);
8903 } else if (symbol
.GetType() && flag
== Symbol::Flag::Subroutine
) {
8905 name
, symbol
, "Cannot call function '%s' like a subroutine"_err_en_US
);
8906 context().SetError(symbol
);
8907 } else if (symbol
.attrs().test(Attr::INTRINSIC
)) {
8908 AcquireIntrinsicProcedureFlags(symbol
);
8913 bool ModuleVisitor::Pre(const parser::AccessStmt
&x
) {
8914 Attr accessAttr
{AccessSpecToAttr(std::get
<parser::AccessSpec
>(x
.t
))};
8915 if (!currScope().IsModule()) { // C869
8916 Say(currStmtSource().value(),
8917 "%s statement may only appear in the specification part of a module"_err_en_US
,
8918 EnumToString(accessAttr
));
8921 const auto &accessIds
{std::get
<std::list
<parser::AccessId
>>(x
.t
)};
8922 if (accessIds
.empty()) {
8923 if (prevAccessStmt_
) { // C869
8924 Say("The default accessibility of this module has already been declared"_err_en_US
)
8925 .Attach(*prevAccessStmt_
, "Previous declaration"_en_US
);
8927 prevAccessStmt_
= currStmtSource();
8928 auto *moduleDetails
{DEREF(currScope().symbol()).detailsIf
<ModuleDetails
>()};
8929 DEREF(moduleDetails
).set_isDefaultPrivate(accessAttr
== Attr::PRIVATE
);
8931 for (const auto &accessId
: accessIds
) {
8932 GenericSpecInfo info
{accessId
.v
.value()};
8933 auto *symbol
{FindInScope(info
.symbolName())};
8934 if (!symbol
&& !info
.kind().IsName()) {
8935 symbol
= &MakeSymbol(info
.symbolName(), Attrs
{}, GenericDetails
{});
8937 info
.Resolve(&SetAccess(info
.symbolName(), accessAttr
, symbol
));
8943 // Set the access specification for this symbol.
8944 Symbol
&ModuleVisitor::SetAccess(
8945 const SourceName
&name
, Attr attr
, Symbol
*symbol
) {
8947 symbol
= &MakeSymbol(name
);
8949 Attrs
&attrs
{symbol
->attrs()};
8950 if (attrs
.HasAny({Attr::PUBLIC
, Attr::PRIVATE
})) {
8951 // PUBLIC/PRIVATE already set: make it a fatal error if it changed
8952 Attr prev
{attrs
.test(Attr::PUBLIC
) ? Attr::PUBLIC
: Attr::PRIVATE
};
8955 "The accessibility of '%s' has already been specified as %s"_err_en_US
,
8956 MakeOpName(name
), EnumToString(prev
));
8958 context().Warn(common::LanguageFeature::RedundantAttribute
, name
,
8959 "The accessibility of '%s' has already been specified as %s"_warn_en_US
,
8960 MakeOpName(name
), EnumToString(prev
));
8968 static bool NeedsExplicitType(const Symbol
&symbol
) {
8969 if (symbol
.has
<UnknownDetails
>()) {
8971 } else if (const auto *details
{symbol
.detailsIf
<EntityDetails
>()}) {
8972 return !details
->type();
8973 } else if (const auto *details
{symbol
.detailsIf
<ObjectEntityDetails
>()}) {
8974 return !details
->type();
8975 } else if (const auto *details
{symbol
.detailsIf
<ProcEntityDetails
>()}) {
8976 return !details
->procInterface() && !details
->type();
8982 void ResolveNamesVisitor::HandleDerivedTypesInImplicitStmts(
8983 const parser::ImplicitPart
&implicitPart
,
8984 const std::list
<parser::DeclarationConstruct
> &decls
) {
8985 // Detect derived type definitions and create symbols for them now if
8986 // they appear in IMPLICIT statements so that these forward-looking
8987 // references will not be ambiguous with host associations.
8988 std::set
<SourceName
> implicitDerivedTypes
;
8989 for (const auto &ipStmt
: implicitPart
.v
) {
8990 if (const auto *impl
{std::get_if
<
8991 parser::Statement
<common::Indirection
<parser::ImplicitStmt
>>>(
8993 if (const auto *specs
{std::get_if
<std::list
<parser::ImplicitSpec
>>(
8994 &impl
->statement
.value().u
)}) {
8995 for (const auto &spec
: *specs
) {
8996 const auto &declTypeSpec
{
8997 std::get
<parser::DeclarationTypeSpec
>(spec
.t
)};
8998 if (const auto *dtSpec
{common::visit(
9000 [](const parser::DeclarationTypeSpec::Type
&x
) {
9003 [](const parser::DeclarationTypeSpec::Class
&x
) {
9006 [](const auto &) -> const parser::DerivedTypeSpec
* {
9010 implicitDerivedTypes
.emplace(
9011 std::get
<parser::Name
>(dtSpec
->t
).source
);
9017 if (!implicitDerivedTypes
.empty()) {
9018 for (const auto &decl
: decls
) {
9019 if (const auto *spec
{
9020 std::get_if
<parser::SpecificationConstruct
>(&decl
.u
)}) {
9021 if (const auto *dtDef
{
9022 std::get_if
<common::Indirection
<parser::DerivedTypeDef
>>(
9024 const parser::DerivedTypeStmt
&dtStmt
{
9025 std::get
<parser::Statement
<parser::DerivedTypeStmt
>>(
9028 const parser::Name
&name
{std::get
<parser::Name
>(dtStmt
.t
)};
9029 if (implicitDerivedTypes
.find(name
.source
) !=
9030 implicitDerivedTypes
.end() &&
9031 !FindInScope(name
)) {
9032 DerivedTypeDetails details
;
9033 details
.set_isForwardReferenced(true);
9034 Resolve(name
, MakeSymbol(name
, std::move(details
)));
9035 implicitDerivedTypes
.erase(name
.source
);
9043 bool ResolveNamesVisitor::Pre(const parser::SpecificationPart
&x
) {
9044 const auto &[accDecls
, ompDecls
, compilerDirectives
, useStmts
, importStmts
,
9045 implicitPart
, decls
] = x
.t
;
9046 auto flagRestorer
{common::ScopedSet(inSpecificationPart_
, true)};
9048 common::ScopedSet(specPartState_
, SpecificationPartState
{})};
9051 Walk(compilerDirectives
);
9052 for (const auto &useStmt
: useStmts
) {
9053 CollectUseRenames(useStmt
.statement
.value());
9056 UseCUDABuiltinNames();
9061 HandleDerivedTypesInImplicitStmts(implicitPart
, decls
);
9063 for (const auto &decl
: decls
) {
9064 if (const auto *spec
{
9065 std::get_if
<parser::SpecificationConstruct
>(&decl
.u
)}) {
9066 PreSpecificationConstruct(*spec
);
9070 FinishSpecificationPart(decls
);
9074 void ResolveNamesVisitor::UseCUDABuiltinNames() {
9075 if (FindCUDADeviceContext(&currScope())) {
9076 for (const auto &[name
, symbol
] : context().GetCUDABuiltinsScope()) {
9077 if (!FindInScope(name
)) {
9078 auto &localSymbol
{MakeSymbol(name
)};
9079 localSymbol
.set_details(UseDetails
{name
, *symbol
});
9080 localSymbol
.flags() = symbol
->flags();
9086 // Initial processing on specification constructs, before visiting them.
9087 void ResolveNamesVisitor::PreSpecificationConstruct(
9088 const parser::SpecificationConstruct
&spec
) {
9091 [&](const parser::Statement
<Indirection
<parser::GenericStmt
>> &y
) {
9092 CreateGeneric(std::get
<parser::GenericSpec
>(y
.statement
.value().t
));
9094 [&](const Indirection
<parser::InterfaceBlock
> &y
) {
9095 const auto &stmt
{std::get
<parser::Statement
<parser::InterfaceStmt
>>(
9097 if (const auto *spec
{parser::Unwrap
<parser::GenericSpec
>(stmt
)}) {
9098 CreateGeneric(*spec
);
9101 [&](const parser::Statement
<parser::OtherSpecificationStmt
> &y
) {
9104 [&](const common::Indirection
<parser::CommonStmt
> &z
) {
9105 CreateCommonBlockSymbols(z
.value());
9107 [&](const common::Indirection
<parser::TargetStmt
> &z
) {
9108 CreateObjectSymbols(z
.value().v
, Attr::TARGET
);
9110 [](const auto &) {},
9114 [](const auto &) {},
9119 void ResolveNamesVisitor::CreateCommonBlockSymbols(
9120 const parser::CommonStmt
&commonStmt
) {
9121 for (const parser::CommonStmt::Block
&block
: commonStmt
.blocks
) {
9122 const auto &[name
, objects
] = block
.t
;
9123 Symbol
&commonBlock
{MakeCommonBlockSymbol(name
)};
9124 for (const auto &object
: objects
) {
9125 Symbol
&obj
{DeclareObjectEntity(std::get
<parser::Name
>(object
.t
))};
9126 if (auto *details
{obj
.detailsIf
<ObjectEntityDetails
>()}) {
9127 details
->set_commonBlock(commonBlock
);
9128 commonBlock
.get
<CommonBlockDetails
>().add_object(obj
);
9134 void ResolveNamesVisitor::CreateObjectSymbols(
9135 const std::list
<parser::ObjectDecl
> &decls
, Attr attr
) {
9136 for (const parser::ObjectDecl
&decl
: decls
) {
9137 SetImplicitAttr(DeclareEntity
<ObjectEntityDetails
>(
9138 std::get
<parser::ObjectName
>(decl
.t
), Attrs
{}),
9143 void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec
&x
) {
9144 auto info
{GenericSpecInfo
{x
}};
9145 SourceName symbolName
{info
.symbolName()};
9146 if (IsLogicalConstant(context(), symbolName
)) {
9148 "Logical constant '%s' may not be used as a defined operator"_err_en_US
);
9151 GenericDetails genericDetails
;
9152 Symbol
*existing
{nullptr};
9153 // Check all variants of names, e.g. "operator(.ne.)" for "operator(/=)"
9154 for (const std::string
&n
: GetAllNames(context(), symbolName
)) {
9155 existing
= currScope().FindSymbol(SourceName
{n
});
9161 Symbol
&ultimate
{existing
->GetUltimate()};
9162 if (auto *existingGeneric
{ultimate
.detailsIf
<GenericDetails
>()}) {
9163 if (&existing
->owner() == &currScope()) {
9164 if (const auto *existingUse
{existing
->detailsIf
<UseDetails
>()}) {
9165 // Create a local copy of a use associated generic so that
9166 // it can be locally extended without corrupting the original.
9167 genericDetails
.CopyFrom(*existingGeneric
);
9168 if (existingGeneric
->specific()) {
9169 genericDetails
.set_specific(*existingGeneric
->specific());
9172 genericDetails
, existing
->name(), existingUse
->symbol());
9173 } else if (existing
== &ultimate
) {
9174 // Extending an extant generic in the same scope
9175 info
.Resolve(existing
);
9178 // Host association of a generic is handled elsewhere
9179 CHECK(existing
->has
<HostAssocDetails
>());
9182 // Create a new generic for this scope.
9184 } else if (ultimate
.has
<SubprogramDetails
>() ||
9185 ultimate
.has
<SubprogramNameDetails
>()) {
9186 genericDetails
.set_specific(*existing
);
9187 } else if (ultimate
.has
<ProcEntityDetails
>()) {
9188 if (existing
->name() != symbolName
||
9189 !ultimate
.attrs().test(Attr::INTRINSIC
)) {
9190 genericDetails
.set_specific(*existing
);
9192 } else if (ultimate
.has
<DerivedTypeDetails
>()) {
9193 genericDetails
.set_derivedType(*existing
);
9194 } else if (&existing
->owner() == &currScope()) {
9195 SayAlreadyDeclared(symbolName
, *existing
);
9198 if (&existing
->owner() == &currScope()) {
9199 EraseSymbol(*existing
);
9202 info
.Resolve(&MakeSymbol(symbolName
, Attrs
{}, std::move(genericDetails
)));
9205 void ResolveNamesVisitor::FinishSpecificationPart(
9206 const std::list
<parser::DeclarationConstruct
> &decls
) {
9207 misparsedStmtFuncFound_
= false;
9208 funcResultStack().CompleteFunctionResultType();
9210 for (auto &pair
: currScope()) {
9211 auto &symbol
{*pair
.second
};
9212 if (inInterfaceBlock()) {
9213 ConvertToObjectEntity(symbol
);
9215 if (NeedsExplicitType(symbol
)) {
9216 ApplyImplicitRules(symbol
);
9218 if (IsDummy(symbol
) && isImplicitNoneType() &&
9219 symbol
.test(Symbol::Flag::Implicit
) && !context().HasError(symbol
)) {
9221 "No explicit type declared for dummy argument '%s'"_err_en_US
);
9222 context().SetError(symbol
);
9224 if (symbol
.has
<GenericDetails
>()) {
9225 CheckGenericProcedures(symbol
);
9227 if (!symbol
.has
<HostAssocDetails
>()) {
9228 CheckPossibleBadForwardRef(symbol
);
9230 // Propagate BIND(C) attribute to procedure entities from their interfaces,
9231 // but not the NAME=, even if it is empty (which would be a reasonable
9232 // and useful behavior, actually). This interpretation is not at all
9233 // clearly described in the standard, but matches the behavior of several
9235 if (auto *proc
{symbol
.detailsIf
<ProcEntityDetails
>()}; proc
&&
9236 !proc
->isDummy() && !IsPointer(symbol
) &&
9237 !symbol
.attrs().test(Attr::BIND_C
)) {
9238 if (const Symbol
* iface
{proc
->procInterface()};
9239 iface
&& IsBindCProcedure(*iface
)) {
9240 SetImplicitAttr(symbol
, Attr::BIND_C
);
9241 SetBindNameOn(symbol
);
9245 currScope().InstantiateDerivedTypes();
9246 for (const auto &decl
: decls
) {
9247 if (const auto *statement
{std::get_if
<
9248 parser::Statement
<common::Indirection
<parser::StmtFunctionStmt
>>>(
9250 messageHandler().set_currStmtSource(statement
->source
);
9251 AnalyzeStmtFunctionStmt(statement
->statement
.value());
9254 // TODO: what about instantiations in BLOCK?
9256 CheckCommonBlocks();
9257 if (!inInterfaceBlock()) {
9258 // TODO: warn for the case where the EQUIVALENCE statement is in a
9259 // procedure declaration in an interface block
9260 CheckEquivalenceSets();
9264 // Analyze the bodies of statement functions now that the symbols in this
9265 // specification part have been fully declared and implicitly typed.
9266 // (Statement function references are not allowed in specification
9267 // expressions, so it's safe to defer processing their definitions.)
9268 void ResolveNamesVisitor::AnalyzeStmtFunctionStmt(
9269 const parser::StmtFunctionStmt
&stmtFunc
) {
9270 const auto &name
{std::get
<parser::Name
>(stmtFunc
.t
)};
9271 Symbol
*symbol
{name
.symbol
};
9272 auto *details
{symbol
? symbol
->detailsIf
<SubprogramDetails
>() : nullptr};
9273 if (!details
|| !symbol
->scope() ||
9274 &symbol
->scope()->parent() != &currScope() || details
->isInterface() ||
9275 details
->isDummy() || details
->entryScope() ||
9276 details
->moduleInterface() || symbol
->test(Symbol::Flag::Subroutine
)) {
9277 return; // error recovery
9279 // Resolve the symbols on the RHS of the statement function.
9280 PushScope(*symbol
->scope());
9281 const auto &parsedExpr
{std::get
<parser::Scalar
<parser::Expr
>>(stmtFunc
.t
)};
9284 if (auto expr
{AnalyzeExpr(context(), stmtFunc
)}) {
9285 if (auto type
{evaluate::DynamicType::From(*symbol
)}) {
9286 if (auto converted
{evaluate::ConvertToType(*type
, std::move(*expr
))}) {
9287 details
->set_stmtFunction(std::move(*converted
));
9290 "Defining expression of statement function '%s' cannot be converted to its result type %s"_err_en_US
,
9291 name
.source
, type
->AsFortran());
9294 details
->set_stmtFunction(std::move(*expr
));
9297 if (!details
->stmtFunction()) {
9298 context().SetError(*symbol
);
9302 void ResolveNamesVisitor::CheckImports() {
9303 auto &scope
{currScope()};
9304 switch (scope
.GetImportKind()) {
9305 case common::ImportKind::None
:
9307 case common::ImportKind::All
:
9308 // C8102: all entities in host must not be hidden
9309 for (const auto &pair
: scope
.parent()) {
9310 auto &name
{pair
.first
};
9311 std::optional
<SourceName
> scopeName
{scope
.GetName()};
9312 if (!scopeName
|| name
!= *scopeName
) {
9313 CheckImport(prevImportStmt_
.value(), name
);
9317 case common::ImportKind::Default
:
9318 case common::ImportKind::Only
:
9319 // C8102: entities named in IMPORT must not be hidden
9320 for (auto &name
: scope
.importNames()) {
9321 CheckImport(name
, name
);
9327 void ResolveNamesVisitor::CheckImport(
9328 const SourceName
&location
, const SourceName
&name
) {
9329 if (auto *symbol
{FindInScope(name
)}) {
9330 const Symbol
&ultimate
{symbol
->GetUltimate()};
9331 if (&ultimate
.owner() == &currScope()) {
9332 Say(location
, "'%s' from host is not accessible"_err_en_US
, name
)
9333 .Attach(symbol
->name(), "'%s' is hidden by this entity"_because_en_US
,
9339 bool ResolveNamesVisitor::Pre(const parser::ImplicitStmt
&x
) {
9340 return CheckNotInBlock("IMPLICIT") && // C1107
9341 ImplicitRulesVisitor::Pre(x
);
9344 void ResolveNamesVisitor::Post(const parser::PointerObject
&x
) {
9345 common::visit(common::visitors
{
9346 [&](const parser::Name
&x
) { ResolveName(x
); },
9347 [&](const parser::StructureComponent
&x
) {
9348 ResolveStructureComponent(x
);
9353 void ResolveNamesVisitor::Post(const parser::AllocateObject
&x
) {
9354 common::visit(common::visitors
{
9355 [&](const parser::Name
&x
) { ResolveName(x
); },
9356 [&](const parser::StructureComponent
&x
) {
9357 ResolveStructureComponent(x
);
9363 bool ResolveNamesVisitor::Pre(const parser::PointerAssignmentStmt
&x
) {
9364 const auto &dataRef
{std::get
<parser::DataRef
>(x
.t
)};
9365 const auto &bounds
{std::get
<parser::PointerAssignmentStmt::Bounds
>(x
.t
)};
9366 const auto &expr
{std::get
<parser::Expr
>(x
.t
)};
9367 ResolveDataRef(dataRef
);
9368 Symbol
*ptrSymbol
{parser::GetLastName(dataRef
).symbol
};
9370 // Resolve unrestricted specific intrinsic procedures as in "p => cos".
9371 if (const parser::Name
* name
{parser::Unwrap
<parser::Name
>(expr
)}) {
9372 if (NameIsKnownOrIntrinsic(*name
)) {
9373 if (Symbol
* symbol
{name
->symbol
}) {
9374 if (IsProcedurePointer(ptrSymbol
) &&
9375 !ptrSymbol
->test(Symbol::Flag::Function
) &&
9376 !ptrSymbol
->test(Symbol::Flag::Subroutine
)) {
9377 if (symbol
->test(Symbol::Flag::Function
)) {
9378 ApplyImplicitRules(*ptrSymbol
);
9381 // If the name is known because it is an object entity from a host
9382 // procedure, create a host associated symbol.
9383 if (symbol
->GetUltimate().has
<ObjectEntityDetails
>() &&
9384 IsUplevelReference(*symbol
)) {
9385 MakeHostAssocSymbol(*name
, *symbol
);
9390 // Can also reference a global external procedure here
9391 if (auto it
{context().globalScope().find(name
->source
)};
9392 it
!= context().globalScope().end()) {
9393 Symbol
&global
{*it
->second
};
9394 if (IsProcedure(global
)) {
9395 Resolve(*name
, global
);
9399 if (IsProcedurePointer(parser::GetLastName(dataRef
).symbol
) &&
9400 !FindSymbol(*name
)) {
9401 // Unknown target of procedure pointer must be an external procedure
9402 Symbol
&symbol
{MakeSymbol(
9403 context().globalScope(), name
->source
, Attrs
{Attr::EXTERNAL
})};
9404 symbol
.implicitAttrs().set(Attr::EXTERNAL
);
9405 Resolve(*name
, symbol
);
9406 ConvertToProcEntity(symbol
, name
->source
);
9413 void ResolveNamesVisitor::Post(const parser::Designator
&x
) {
9414 ResolveDesignator(x
);
9416 void ResolveNamesVisitor::Post(const parser::SubstringInquiry
&x
) {
9417 Walk(std::get
<parser::SubstringRange
>(x
.v
.t
).t
);
9418 ResolveDataRef(std::get
<parser::DataRef
>(x
.v
.t
));
9421 void ResolveNamesVisitor::Post(const parser::ProcComponentRef
&x
) {
9422 ResolveStructureComponent(x
.v
.thing
);
9424 void ResolveNamesVisitor::Post(const parser::TypeGuardStmt
&x
) {
9425 DeclTypeSpecVisitor::Post(x
);
9426 ConstructVisitor::Post(x
);
9428 bool ResolveNamesVisitor::Pre(const parser::StmtFunctionStmt
&x
) {
9429 if (HandleStmtFunction(x
)) {
9432 // This is an array element or pointer-valued function assignment:
9433 // resolve the names of indices/arguments
9434 const auto &names
{std::get
<std::list
<parser::Name
>>(x
.t
)};
9435 for (auto &name
: names
) {
9442 bool ResolveNamesVisitor::Pre(const parser::DefinedOpName
&x
) {
9443 const parser::Name
&name
{x
.v
};
9444 if (FindSymbol(name
)) {
9446 } else if (IsLogicalConstant(context(), name
.source
)) {
9448 "Logical constant '%s' may not be used as a defined operator"_err_en_US
);
9450 // Resolved later in expression semantics
9451 MakePlaceholder(name
, MiscDetails::Kind::TypeBoundDefinedOp
);
9456 void ResolveNamesVisitor::Post(const parser::AssignStmt
&x
) {
9457 if (auto *name
{ResolveName(std::get
<parser::Name
>(x
.t
))}) {
9458 CheckEntryDummyUse(name
->source
, name
->symbol
);
9459 ConvertToObjectEntity(DEREF(name
->symbol
));
9462 void ResolveNamesVisitor::Post(const parser::AssignedGotoStmt
&x
) {
9463 if (auto *name
{ResolveName(std::get
<parser::Name
>(x
.t
))}) {
9464 CheckEntryDummyUse(name
->source
, name
->symbol
);
9465 ConvertToObjectEntity(DEREF(name
->symbol
));
9469 void ResolveNamesVisitor::Post(const parser::CompilerDirective
&x
) {
9470 if (std::holds_alternative
<parser::CompilerDirective::VectorAlways
>(x
.u
) ||
9471 std::holds_alternative
<parser::CompilerDirective::Unroll
>(x
.u
)) {
9474 if (const auto *tkr
{
9475 std::get_if
<std::list
<parser::CompilerDirective::IgnoreTKR
>>(&x
.u
)}) {
9476 if (currScope().IsTopLevel() ||
9477 GetProgramUnitContaining(currScope()).kind() !=
9478 Scope::Kind::Subprogram
) {
9480 "!DIR$ IGNORE_TKR directive must appear in a subroutine or function"_err_en_US
);
9483 if (!inSpecificationPart_
) {
9485 "!DIR$ IGNORE_TKR directive must appear in the specification part"_err_en_US
);
9489 Symbol
*symbol
{currScope().symbol()};
9490 if (SubprogramDetails
*
9491 subp
{symbol
? symbol
->detailsIf
<SubprogramDetails
>() : nullptr}) {
9492 subp
->set_defaultIgnoreTKR(true);
9495 for (const parser::CompilerDirective::IgnoreTKR
&item
: *tkr
) {
9496 common::IgnoreTKRSet set
;
9497 if (const auto &maybeList
{
9498 std::get
<std::optional
<std::list
<const char *>>>(item
.t
)}) {
9499 for (const char *p
: *maybeList
) {
9503 set
.set(common::IgnoreTKR::Type
);
9506 set
.set(common::IgnoreTKR::Kind
);
9509 set
.set(common::IgnoreTKR::Rank
);
9512 set
.set(common::IgnoreTKR::Device
);
9515 set
.set(common::IgnoreTKR::Managed
);
9518 set
.set(common::IgnoreTKR::Contiguous
);
9521 set
= common::ignoreTKRAll
;
9525 "'%c' is not a valid letter for !DIR$ IGNORE_TKR directive"_err_en_US
,
9527 set
= common::ignoreTKRAll
;
9534 "!DIR$ IGNORE_TKR directive may not have an empty parenthesized list of letters"_err_en_US
);
9536 } else { // no (list)
9537 set
= common::ignoreTKRAll
;
9540 const auto &name
{std::get
<parser::Name
>(item
.t
)};
9541 Symbol
*symbol
{FindSymbol(name
)};
9543 symbol
= &MakeSymbol(name
, Attrs
{}, ObjectEntityDetails
{});
9545 if (symbol
->owner() != currScope()) {
9547 name
, *symbol
, "'%s' must be local to this subprogram"_err_en_US
);
9549 ConvertToObjectEntity(*symbol
);
9550 if (auto *object
{symbol
->detailsIf
<ObjectEntityDetails
>()}) {
9551 object
->set_ignoreTKR(set
);
9553 SayWithDecl(name
, *symbol
, "'%s' must be an object"_err_en_US
);
9558 } else if (context().ShouldWarn(common::UsageWarning::IgnoredDirective
)) {
9559 Say(x
.source
, "Unrecognized compiler directive was ignored"_warn_en_US
)
9560 .set_usageWarning(common::UsageWarning::IgnoredDirective
);
9564 bool ResolveNamesVisitor::Pre(const parser::ProgramUnit
&x
) {
9565 if (std::holds_alternative
<common::Indirection
<parser::CompilerDirective
>>(
9567 // TODO: global directives
9570 if (std::holds_alternative
<
9571 common::Indirection
<parser::OpenACCRoutineConstruct
>>(x
.u
)) {
9572 ResolveAccParts(context(), x
, &topScope_
);
9575 ProgramTree
&root
{ProgramTree::Build(x
, context())};
9576 SetScope(topScope_
);
9577 ResolveSpecificationParts(root
);
9578 FinishSpecificationParts(root
);
9579 ResolveExecutionParts(root
);
9580 FinishExecutionParts(root
);
9581 ResolveAccParts(context(), x
, /*topScope=*/nullptr);
9582 ResolveOmpParts(context(), x
);
9586 template <typename A
> std::set
<SourceName
> GetUses(const A
&x
) {
9587 std::set
<SourceName
> uses
;
9588 if constexpr (!std::is_same_v
<A
, parser::CompilerDirective
> &&
9589 !std::is_same_v
<A
, parser::OpenACCRoutineConstruct
>) {
9590 const auto &spec
{std::get
<parser::SpecificationPart
>(x
.t
)};
9591 const auto &unitUses
{std::get
<
9592 std::list
<parser::Statement
<common::Indirection
<parser::UseStmt
>>>>(
9594 for (const auto &u
: unitUses
) {
9595 uses
.insert(u
.statement
.value().moduleName
.source
);
9601 bool ResolveNamesVisitor::Pre(const parser::Program
&x
) {
9602 if (Scope
* hermetic
{context().currentHermeticModuleFileScope()}) {
9603 // Processing either the dependent modules or first module of a
9604 // hermetic module file; ensure that the hermetic module scope has
9605 // its implicit rules map entry.
9606 ImplicitRulesVisitor::BeginScope(*hermetic
);
9608 std::map
<SourceName
, const parser::ProgramUnit
*> modules
;
9609 std::set
<SourceName
> uses
;
9610 bool disordered
{false};
9611 for (const auto &progUnit
: x
.v
) {
9612 if (const auto *indMod
{
9613 std::get_if
<common::Indirection
<parser::Module
>>(&progUnit
.u
)}) {
9614 const parser::Module
&mod
{indMod
->value()};
9615 const auto &moduleStmt
{
9616 std::get
<parser::Statement
<parser::ModuleStmt
>>(mod
.t
)};
9617 const SourceName
&name
{moduleStmt
.statement
.v
.source
};
9618 if (auto iter
{modules
.find(name
)}; iter
!= modules
.end()) {
9620 "Module '%s' appears multiple times in a compilation unit"_err_en_US
)
9621 .Attach(iter
->first
, "First definition of module"_en_US
);
9624 modules
.emplace(name
, &progUnit
);
9625 if (auto iter
{uses
.find(name
)}; iter
!= uses
.end()) {
9626 if (context().ShouldWarn(common::LanguageFeature::MiscUseExtensions
)) {
9628 "A USE statement referencing module '%s' appears earlier in this compilation unit"_port_en_US
,
9630 .Attach(*iter
, "First USE of module"_en_US
);
9635 for (SourceName used
: common::visit(
9636 [](const auto &indUnit
) { return GetUses(indUnit
.value()); },
9644 // Process modules in topological order
9645 std::vector
<const parser::ProgramUnit
*> moduleOrder
;
9646 while (!modules
.empty()) {
9648 for (const auto &pair
: modules
) {
9649 const SourceName
&name
{pair
.first
};
9650 const parser::ProgramUnit
&progUnit
{*pair
.second
};
9651 const parser::Module
&m
{
9652 std::get
<common::Indirection
<parser::Module
>>(progUnit
.u
).value()};
9654 for (const SourceName
&use
: GetUses(m
)) {
9655 if (modules
.find(use
) != modules
.end()) {
9661 moduleOrder
.push_back(&progUnit
);
9662 modules
.erase(name
);
9667 Message
*msg
{nullptr};
9668 for (const auto &pair
: modules
) {
9670 msg
->Attach(pair
.first
, "Module in a cycle"_en_US
);
9672 msg
= &Say(pair
.first
,
9673 "Some modules in this compilation unit form one or more cycles of dependence"_err_en_US
);
9679 // Modules can be ordered. Process them first, and then all of the other
9681 for (const parser::ProgramUnit
*progUnit
: moduleOrder
) {
9684 for (const auto &progUnit
: x
.v
) {
9685 if (!std::get_if
<common::Indirection
<parser::Module
>>(&progUnit
.u
)) {
9692 // References to procedures need to record that their symbols are known
9693 // to be procedures, so that they don't get converted to objects by default.
9694 class ExecutionPartCallSkimmer
: public ExecutionPartSkimmerBase
{
9696 explicit ExecutionPartCallSkimmer(ResolveNamesVisitor
&resolver
)
9697 : resolver_
{resolver
} {}
9699 void Walk(const parser::ExecutionPart
&exec
) {
9700 parser::Walk(exec
, *this);
9704 using ExecutionPartSkimmerBase::Post
;
9705 using ExecutionPartSkimmerBase::Pre
;
9707 void Post(const parser::FunctionReference
&fr
) {
9708 NoteCall(Symbol::Flag::Function
, fr
.v
, false);
9710 void Post(const parser::CallStmt
&cs
) {
9711 NoteCall(Symbol::Flag::Subroutine
, cs
.call
, cs
.chevrons
.has_value());
9716 Symbol::Flag flag
, const parser::Call
&call
, bool hasCUDAChevrons
) {
9717 auto &designator
{std::get
<parser::ProcedureDesignator
>(call
.t
)};
9718 if (const auto *name
{std::get_if
<parser::Name
>(&designator
.u
)}) {
9719 if (!IsHidden(name
->source
)) {
9720 resolver_
.NoteExecutablePartCall(flag
, name
->source
, hasCUDAChevrons
);
9725 ResolveNamesVisitor
&resolver_
;
9728 // Build the scope tree and resolve names in the specification parts of this
9729 // node and its children
9730 void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree
&node
) {
9731 if (node
.isSpecificationPartResolved()) {
9732 return; // been here already
9734 node
.set_isSpecificationPartResolved();
9735 if (!BeginScopeForNode(node
)) {
9736 return; // an error prevented scope from being created
9738 Scope
&scope
{currScope()};
9739 node
.set_scope(scope
);
9742 [&](const auto *x
) {
9749 bool inDeviceSubprogram
{false};
9750 // If this is a function, convert result to an object. This is to prevent the
9751 // result from being converted later to a function symbol if it is called
9752 // inside the function.
9753 // If the result is function pointer, then ConvertToObjectEntity will not
9754 // convert the result to an object, and calling the symbol inside the function
9755 // will result in calls to the result pointer.
9756 // A function cannot be called recursively if RESULT was not used to define a
9757 // distinct result name (15.6.2.2 point 4.).
9758 if (Symbol
* symbol
{scope
.symbol()}) {
9759 if (auto *details
{symbol
->detailsIf
<SubprogramDetails
>()}) {
9760 if (details
->isFunction()) {
9761 ConvertToObjectEntity(const_cast<Symbol
&>(details
->result()));
9763 // Check the current procedure is a device procedure to apply implicit
9764 // attribute at the end.
9765 if (auto attrs
{details
->cudaSubprogramAttrs()}) {
9766 if (*attrs
== common::CUDASubprogramAttrs::Device
||
9767 *attrs
== common::CUDASubprogramAttrs::Global
||
9768 *attrs
== common::CUDASubprogramAttrs::Grid_Global
) {
9769 inDeviceSubprogram
= true;
9774 if (node
.IsModule()) {
9775 ApplyDefaultAccess();
9777 for (auto &child
: node
.children()) {
9778 ResolveSpecificationParts(child
);
9781 ExecutionPartCallSkimmer
{*this}.Walk(*node
.exec());
9782 HandleImpliedAsynchronousInScope(node
.exec()->v
);
9784 EndScopeForNode(node
);
9785 // Ensure that every object entity has a type.
9786 bool inModule
{node
.GetKind() == ProgramTree::Kind::Module
||
9787 node
.GetKind() == ProgramTree::Kind::Submodule
};
9788 for (auto &pair
: *node
.scope()) {
9789 Symbol
&symbol
{*pair
.second
};
9790 if (inModule
&& symbol
.attrs().test(Attr::EXTERNAL
) && !IsPointer(symbol
) &&
9791 !symbol
.test(Symbol::Flag::Function
) &&
9792 !symbol
.test(Symbol::Flag::Subroutine
)) {
9793 // in a module, external proc without return type is subroutine
9795 symbol
.GetType() ? Symbol::Flag::Function
: Symbol::Flag::Subroutine
);
9797 ApplyImplicitRules(symbol
);
9798 // Apply CUDA implicit attributes if needed.
9799 if (inDeviceSubprogram
&& symbol
.has
<ObjectEntityDetails
>()) {
9800 auto *object
{symbol
.detailsIf
<ObjectEntityDetails
>()};
9801 if (!object
->cudaDataAttr() && !IsValue(symbol
) &&
9802 (IsDummy(symbol
) || object
->IsArray())) {
9803 // Implicitly set device attribute if none is set in device context.
9804 object
->set_cudaDataAttr(common::CUDADataAttr::Device
);
9810 // Add SubprogramNameDetails symbols for module and internal subprograms and
9811 // their ENTRY statements.
9812 void ResolveNamesVisitor::AddSubpNames(ProgramTree
&node
) {
9814 node
.IsModule() ? SubprogramKind::Module
: SubprogramKind::Internal
};
9815 for (auto &child
: node
.children()) {
9816 auto &symbol
{MakeSymbol(child
.name(), SubprogramNameDetails
{kind
, child
})};
9817 if (child
.HasModulePrefix()) {
9818 SetExplicitAttr(symbol
, Attr::MODULE
);
9820 if (child
.bindingSpec()) {
9821 SetExplicitAttr(symbol
, Attr::BIND_C
);
9823 auto childKind
{child
.GetKind()};
9824 if (childKind
== ProgramTree::Kind::Function
) {
9825 symbol
.set(Symbol::Flag::Function
);
9826 } else if (childKind
== ProgramTree::Kind::Subroutine
) {
9827 symbol
.set(Symbol::Flag::Subroutine
);
9829 continue; // make ENTRY symbols only where valid
9831 for (const auto &entryStmt
: child
.entryStmts()) {
9832 SubprogramNameDetails details
{kind
, child
};
9834 MakeSymbol(std::get
<parser::Name
>(entryStmt
->t
), std::move(details
))};
9835 symbol
.set(child
.GetSubpFlag());
9836 if (child
.HasModulePrefix()) {
9837 SetExplicitAttr(symbol
, Attr::MODULE
);
9839 if (child
.bindingSpec()) {
9840 SetExplicitAttr(symbol
, Attr::BIND_C
);
9844 for (const auto &generic
: node
.genericSpecs()) {
9845 if (const auto *name
{std::get_if
<parser::Name
>(&generic
->u
)}) {
9846 if (currScope().find(name
->source
) != currScope().end()) {
9847 // If this scope has both a generic interface and a contained
9848 // subprogram with the same name, create the generic's symbol
9849 // now so that any other generics of the same name that are pulled
9850 // into scope later via USE association will properly merge instead
9851 // of raising a bogus error due a conflict with the subprogram.
9852 CreateGeneric(*generic
);
9858 // Push a new scope for this node or return false on error.
9859 bool ResolveNamesVisitor::BeginScopeForNode(const ProgramTree
&node
) {
9860 switch (node
.GetKind()) {
9861 SWITCH_COVERS_ALL_CASES
9862 case ProgramTree::Kind::Program
:
9863 PushScope(Scope::Kind::MainProgram
,
9864 &MakeSymbol(node
.name(), MainProgramDetails
{}));
9866 case ProgramTree::Kind::Function
:
9867 case ProgramTree::Kind::Subroutine
:
9868 return BeginSubprogram(node
.name(), node
.GetSubpFlag(),
9869 node
.HasModulePrefix(), node
.bindingSpec(), &node
.entryStmts());
9870 case ProgramTree::Kind::MpSubprogram
:
9871 return BeginMpSubprogram(node
.name());
9872 case ProgramTree::Kind::Module
:
9873 BeginModule(node
.name(), false);
9875 case ProgramTree::Kind::Submodule
:
9876 return BeginSubmodule(node
.name(), node
.GetParentId());
9877 case ProgramTree::Kind::BlockData
:
9878 PushBlockDataScope(node
.name());
9883 void ResolveNamesVisitor::EndScopeForNode(const ProgramTree
&node
) {
9884 std::optional
<parser::CharBlock
> stmtSource
;
9885 const std::optional
<parser::LanguageBindingSpec
> *binding
{nullptr};
9888 [&](const parser::Statement
<parser::FunctionStmt
> *stmt
) {
9890 stmtSource
= stmt
->source
;
9891 if (const auto &maybeSuffix
{
9892 std::get
<std::optional
<parser::Suffix
>>(
9893 stmt
->statement
.t
)}) {
9894 binding
= &maybeSuffix
->binding
;
9898 [&](const parser::Statement
<parser::SubroutineStmt
> *stmt
) {
9900 stmtSource
= stmt
->source
;
9901 binding
= &std::get
<std::optional
<parser::LanguageBindingSpec
>>(
9905 [](const auto *) {},
9908 EndSubprogram(stmtSource
, binding
, &node
.entryStmts());
9911 // Some analyses and checks, such as the processing of initializers of
9912 // pointers, are deferred until all of the pertinent specification parts
9913 // have been visited. This deferred processing enables the use of forward
9914 // references in these circumstances.
9915 // Data statement objects with implicit derived types are finally
9917 class DeferredCheckVisitor
{
9919 explicit DeferredCheckVisitor(ResolveNamesVisitor
&resolver
)
9920 : resolver_
{resolver
} {}
9922 template <typename A
> void Walk(const A
&x
) { parser::Walk(x
, *this); }
9924 template <typename A
> bool Pre(const A
&) { return true; }
9925 template <typename A
> void Post(const A
&) {}
9927 void Post(const parser::DerivedTypeStmt
&x
) {
9928 const auto &name
{std::get
<parser::Name
>(x
.t
)};
9929 if (Symbol
* symbol
{name
.symbol
}) {
9930 if (Scope
* scope
{symbol
->scope()}) {
9931 if (scope
->IsDerivedType()) {
9932 CHECK(outerScope_
== nullptr);
9933 outerScope_
= &resolver_
.currScope();
9934 resolver_
.SetScope(*scope
);
9939 void Post(const parser::EndTypeStmt
&) {
9941 resolver_
.SetScope(*outerScope_
);
9942 outerScope_
= nullptr;
9946 void Post(const parser::ProcInterface
&pi
) {
9947 if (const auto *name
{std::get_if
<parser::Name
>(&pi
.u
)}) {
9948 resolver_
.CheckExplicitInterface(*name
);
9951 bool Pre(const parser::EntityDecl
&decl
) {
9952 Init(std::get
<parser::Name
>(decl
.t
),
9953 std::get
<std::optional
<parser::Initialization
>>(decl
.t
));
9956 bool Pre(const parser::ComponentDecl
&decl
) {
9957 Init(std::get
<parser::Name
>(decl
.t
),
9958 std::get
<std::optional
<parser::Initialization
>>(decl
.t
));
9961 bool Pre(const parser::ProcDecl
&decl
) {
9962 if (const auto &init
{
9963 std::get
<std::optional
<parser::ProcPointerInit
>>(decl
.t
)}) {
9964 resolver_
.PointerInitialization(std::get
<parser::Name
>(decl
.t
), *init
);
9968 void Post(const parser::TypeBoundProcedureStmt::WithInterface
&tbps
) {
9969 resolver_
.CheckExplicitInterface(tbps
.interfaceName
);
9971 void Post(const parser::TypeBoundProcedureStmt::WithoutInterface
&tbps
) {
9973 resolver_
.CheckBindings(tbps
);
9976 bool Pre(const parser::DataStmtObject
&) {
9977 ++dataStmtObjectNesting_
;
9980 void Post(const parser::DataStmtObject
&) { --dataStmtObjectNesting_
; }
9981 void Post(const parser::Designator
&x
) {
9982 if (dataStmtObjectNesting_
> 0) {
9983 resolver_
.ResolveDesignator(x
);
9988 void Init(const parser::Name
&name
,
9989 const std::optional
<parser::Initialization
> &init
) {
9991 if (const auto *target
{
9992 std::get_if
<parser::InitialDataTarget
>(&init
->u
)}) {
9993 resolver_
.PointerInitialization(name
, *target
);
9994 } else if (const auto *expr
{
9995 std::get_if
<parser::ConstantExpr
>(&init
->u
)}) {
9997 if (const auto *object
{name
.symbol
->detailsIf
<ObjectEntityDetails
>()};
9998 !object
|| !object
->init()) {
9999 resolver_
.NonPointerInitialization(name
, *expr
);
10006 ResolveNamesVisitor
&resolver_
;
10007 Scope
*outerScope_
{nullptr};
10008 int dataStmtObjectNesting_
{0};
10011 // Perform checks and completions that need to happen after all of
10012 // the specification parts but before any of the execution parts.
10013 void ResolveNamesVisitor::FinishSpecificationParts(const ProgramTree
&node
) {
10014 if (!node
.scope()) {
10015 return; // error occurred creating scope
10017 auto flagRestorer
{common::ScopedSet(inSpecificationPart_
, true)};
10018 SetScope(*node
.scope());
10019 // The initializers of pointers and non-PARAMETER objects, the default
10020 // initializers of components, and non-deferred type-bound procedure
10021 // bindings have not yet been traversed.
10022 // We do that now, when any forward references that appeared
10023 // in those initializers will resolve to the right symbols without
10024 // incurring spurious errors with IMPLICIT NONE or forward references
10025 // to nested subprograms.
10026 DeferredCheckVisitor
{*this}.Walk(node
.spec());
10027 for (Scope
&childScope
: currScope().children()) {
10028 if (childScope
.IsParameterizedDerivedTypeInstantiation()) {
10029 FinishDerivedTypeInstantiation(childScope
);
10032 for (const auto &child
: node
.children()) {
10033 FinishSpecificationParts(child
);
10037 void ResolveNamesVisitor::FinishExecutionParts(const ProgramTree
&node
) {
10038 if (node
.scope()) {
10039 SetScope(*node
.scope());
10041 DeferredCheckVisitor
{*this}.Walk(*node
.exec());
10043 for (const auto &child
: node
.children()) {
10044 FinishExecutionParts(child
);
10049 // Duplicate and fold component object pointer default initializer designators
10050 // using the actual type parameter values of each particular instantiation.
10051 // Validation is done later in declaration checking.
10052 void ResolveNamesVisitor::FinishDerivedTypeInstantiation(Scope
&scope
) {
10053 CHECK(scope
.IsDerivedType() && !scope
.symbol());
10054 if (DerivedTypeSpec
* spec
{scope
.derivedTypeSpec()}) {
10055 spec
->Instantiate(currScope());
10056 const Symbol
&origTypeSymbol
{spec
->typeSymbol()};
10057 if (const Scope
* origTypeScope
{origTypeSymbol
.scope()}) {
10058 CHECK(origTypeScope
->IsDerivedType() &&
10059 origTypeScope
->symbol() == &origTypeSymbol
);
10060 auto &foldingContext
{GetFoldingContext()};
10061 auto restorer
{foldingContext
.WithPDTInstance(*spec
)};
10062 for (auto &pair
: scope
) {
10063 Symbol
&comp
{*pair
.second
};
10064 const Symbol
&origComp
{DEREF(FindInScope(*origTypeScope
, comp
.name()))};
10065 if (IsPointer(comp
)) {
10066 if (auto *details
{comp
.detailsIf
<ObjectEntityDetails
>()}) {
10067 auto origDetails
{origComp
.get
<ObjectEntityDetails
>()};
10068 if (const MaybeExpr
& init
{origDetails
.init()}) {
10069 SomeExpr newInit
{*init
};
10070 MaybeExpr folded
{FoldExpr(std::move(newInit
))};
10071 details
->set_init(std::move(folded
));
10080 // Resolve names in the execution part of this node and its children
10081 void ResolveNamesVisitor::ResolveExecutionParts(const ProgramTree
&node
) {
10082 if (!node
.scope()) {
10083 return; // error occurred creating scope
10085 SetScope(*node
.scope());
10086 if (const auto *exec
{node
.exec()}) {
10090 if (node
.IsModule()) {
10091 // A second final pass to catch new symbols added from implicitly
10092 // typed names in NAMELIST groups or the specification parts of
10093 // module subprograms.
10094 ApplyDefaultAccess();
10096 PopScope(); // converts unclassified entities into objects
10097 for (const auto &child
: node
.children()) {
10098 ResolveExecutionParts(child
);
10102 void ResolveNamesVisitor::Post(const parser::Program
&x
) {
10103 // ensure that all temps were deallocated
10105 CHECK(!cudaDataAttr_
);
10106 CHECK(!GetDeclTypeSpec());
10107 // Top-level resolution to propagate information across program units after
10108 // each of them has been resolved separately.
10109 ResolveOmpTopLevelParts(context(), x
);
10112 // A singleton instance of the scope -> IMPLICIT rules mapping is
10113 // shared by all instances of ResolveNamesVisitor and accessed by this
10114 // pointer when the visitors (other than the top-level original) are
10116 static ImplicitRulesMap
*sharedImplicitRulesMap
{nullptr};
10119 SemanticsContext
&context
, const parser::Program
&program
, Scope
&top
) {
10120 ImplicitRulesMap implicitRulesMap
;
10121 auto restorer
{common::ScopedSet(sharedImplicitRulesMap
, &implicitRulesMap
)};
10122 ResolveNamesVisitor
{context
, implicitRulesMap
, top
}.Walk(program
);
10123 return !context
.AnyFatalError();
10126 // Processes a module (but not internal) function when it is referenced
10127 // in a specification expression in a sibling procedure.
10128 void ResolveSpecificationParts(
10129 SemanticsContext
&context
, const Symbol
&subprogram
) {
10130 auto originalLocation
{context
.location()};
10131 ImplicitRulesMap implicitRulesMap
;
10132 bool localImplicitRulesMap
{false};
10133 if (!sharedImplicitRulesMap
) {
10134 sharedImplicitRulesMap
= &implicitRulesMap
;
10135 localImplicitRulesMap
= true;
10137 ResolveNamesVisitor visitor
{
10138 context
, *sharedImplicitRulesMap
, context
.globalScope()};
10139 const auto &details
{subprogram
.get
<SubprogramNameDetails
>()};
10140 ProgramTree
&node
{details
.node()};
10141 const Scope
&moduleScope
{subprogram
.owner()};
10142 if (localImplicitRulesMap
) {
10143 visitor
.BeginScope(const_cast<Scope
&>(moduleScope
));
10145 visitor
.SetScope(const_cast<Scope
&>(moduleScope
));
10147 visitor
.ResolveSpecificationParts(node
);
10148 context
.set_location(std::move(originalLocation
));
10149 if (localImplicitRulesMap
) {
10150 sharedImplicitRulesMap
= nullptr;
10154 } // namespace Fortran::semantics