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