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