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/Common/visit.h" 21 #include "flang/Evaluate/characteristics.h" 22 #include "flang/Evaluate/check-expression.h" 23 #include "flang/Evaluate/common.h" 24 #include "flang/Evaluate/fold-designator.h" 25 #include "flang/Evaluate/fold.h" 26 #include "flang/Evaluate/intrinsics.h" 27 #include "flang/Evaluate/tools.h" 28 #include "flang/Evaluate/type.h" 29 #include "flang/Parser/parse-tree-visitor.h" 30 #include "flang/Parser/parse-tree.h" 31 #include "flang/Parser/tools.h" 32 #include "flang/Semantics/attr.h" 33 #include "flang/Semantics/expression.h" 34 #include "flang/Semantics/scope.h" 35 #include "flang/Semantics/semantics.h" 36 #include "flang/Semantics/symbol.h" 37 #include "flang/Semantics/tools.h" 38 #include "flang/Semantics/type.h" 39 #include "llvm/Support/raw_ostream.h" 40 #include <list> 41 #include <map> 42 #include <set> 43 #include <stack> 44 45 namespace Fortran::semantics { 46 47 using namespace parser::literals; 48 49 template <typename T> using Indirection = common::Indirection<T>; 50 using Message = parser::Message; 51 using Messages = parser::Messages; 52 using MessageFixedText = parser::MessageFixedText; 53 using MessageFormattedText = parser::MessageFormattedText; 54 55 class ResolveNamesVisitor; 56 class ScopeHandler; 57 58 // ImplicitRules maps initial character of identifier to the DeclTypeSpec 59 // representing the implicit type; std::nullopt if none. 60 // It also records the presence of IMPLICIT NONE statements. 61 // When inheritFromParent is set, defaults come from the parent rules. 62 class ImplicitRules { 63 public: 64 ImplicitRules(SemanticsContext &context, ImplicitRules *parent) 65 : parent_{parent}, context_{context} { 66 inheritFromParent_ = parent != nullptr; 67 } 68 bool isImplicitNoneType() const; 69 bool isImplicitNoneExternal() const; 70 void set_isImplicitNoneType(bool x) { isImplicitNoneType_ = x; } 71 void set_isImplicitNoneExternal(bool x) { isImplicitNoneExternal_ = x; } 72 void set_inheritFromParent(bool x) { inheritFromParent_ = x; } 73 // Get the implicit type for this name. May be null. 74 const DeclTypeSpec *GetType( 75 SourceName, bool respectImplicitNone = true) const; 76 // Record the implicit type for the range of characters [fromLetter, 77 // toLetter]. 78 void SetTypeMapping(const DeclTypeSpec &type, parser::Location fromLetter, 79 parser::Location toLetter); 80 81 private: 82 static char Incr(char ch); 83 84 ImplicitRules *parent_; 85 SemanticsContext &context_; 86 bool inheritFromParent_{false}; // look in parent if not specified here 87 bool isImplicitNoneType_{ 88 context_.IsEnabled(common::LanguageFeature::ImplicitNoneTypeAlways)}; 89 bool isImplicitNoneExternal_{false}; 90 // map_ contains the mapping between letters and types that were defined 91 // by the IMPLICIT statements of the related scope. It does not contain 92 // the default Fortran mappings nor the mapping defined in parents. 93 std::map<char, common::Reference<const DeclTypeSpec>> map_; 94 95 friend llvm::raw_ostream &operator<<( 96 llvm::raw_ostream &, const ImplicitRules &); 97 friend void ShowImplicitRule( 98 llvm::raw_ostream &, const ImplicitRules &, char); 99 }; 100 101 // scope -> implicit rules for that scope 102 using ImplicitRulesMap = std::map<const Scope *, ImplicitRules>; 103 104 // Track statement source locations and save messages. 105 class MessageHandler { 106 public: 107 MessageHandler() { DIE("MessageHandler: default-constructed"); } 108 explicit MessageHandler(SemanticsContext &c) : context_{&c} {} 109 Messages &messages() { return context_->messages(); }; 110 const std::optional<SourceName> &currStmtSource() { 111 return context_->location(); 112 } 113 void set_currStmtSource(const std::optional<SourceName> &source) { 114 context_->set_location(source); 115 } 116 117 // Emit a message associated with the current statement source. 118 Message &Say(MessageFixedText &&); 119 Message &Say(MessageFormattedText &&); 120 // Emit a message about a SourceName 121 Message &Say(const SourceName &, MessageFixedText &&); 122 // Emit a formatted message associated with a source location. 123 template <typename... A> 124 Message &Say(const SourceName &source, MessageFixedText &&msg, A &&...args) { 125 return context_->Say(source, std::move(msg), std::forward<A>(args)...); 126 } 127 128 private: 129 SemanticsContext *context_; 130 }; 131 132 // Inheritance graph for the parse tree visitation classes that follow: 133 // BaseVisitor 134 // + AttrsVisitor 135 // | + DeclTypeSpecVisitor 136 // | + ImplicitRulesVisitor 137 // | + ScopeHandler -----------+--+ 138 // | + ModuleVisitor ========|==+ 139 // | + InterfaceVisitor | | 140 // | +-+ SubprogramVisitor ==|==+ 141 // + ArraySpecVisitor | | 142 // + DeclarationVisitor <--------+ | 143 // + ConstructVisitor | 144 // + ResolveNamesVisitor <------+ 145 146 class BaseVisitor { 147 public: 148 BaseVisitor() { DIE("BaseVisitor: default-constructed"); } 149 BaseVisitor( 150 SemanticsContext &c, ResolveNamesVisitor &v, ImplicitRulesMap &rules) 151 : implicitRulesMap_{&rules}, this_{&v}, context_{&c}, messageHandler_{c} { 152 } 153 template <typename T> void Walk(const T &); 154 155 MessageHandler &messageHandler() { return messageHandler_; } 156 const std::optional<SourceName> &currStmtSource() { 157 return context_->location(); 158 } 159 SemanticsContext &context() const { return *context_; } 160 evaluate::FoldingContext &GetFoldingContext() const { 161 return context_->foldingContext(); 162 } 163 bool IsIntrinsic( 164 const SourceName &name, std::optional<Symbol::Flag> flag) const { 165 if (!flag) { 166 return context_->intrinsics().IsIntrinsic(name.ToString()); 167 } else if (flag == Symbol::Flag::Function) { 168 return context_->intrinsics().IsIntrinsicFunction(name.ToString()); 169 } else if (flag == Symbol::Flag::Subroutine) { 170 return context_->intrinsics().IsIntrinsicSubroutine(name.ToString()); 171 } else { 172 DIE("expected Subroutine or Function flag"); 173 } 174 } 175 176 // Make a placeholder symbol for a Name that otherwise wouldn't have one. 177 // It is not in any scope and always has MiscDetails. 178 void MakePlaceholder(const parser::Name &, MiscDetails::Kind); 179 180 template <typename T> common::IfNoLvalue<T, T> FoldExpr(T &&expr) { 181 return evaluate::Fold(GetFoldingContext(), std::move(expr)); 182 } 183 184 template <typename T> MaybeExpr EvaluateExpr(const T &expr) { 185 return FoldExpr(AnalyzeExpr(*context_, expr)); 186 } 187 188 template <typename T> 189 MaybeExpr EvaluateNonPointerInitializer( 190 const Symbol &symbol, const T &expr, parser::CharBlock source) { 191 if (!context().HasError(symbol)) { 192 if (auto maybeExpr{AnalyzeExpr(*context_, expr)}) { 193 auto restorer{GetFoldingContext().messages().SetLocation(source)}; 194 return evaluate::NonPointerInitializationExpr( 195 symbol, std::move(*maybeExpr), GetFoldingContext()); 196 } 197 } 198 return std::nullopt; 199 } 200 201 template <typename T> MaybeIntExpr EvaluateIntExpr(const T &expr) { 202 return semantics::EvaluateIntExpr(*context_, expr); 203 } 204 205 template <typename T> 206 MaybeSubscriptIntExpr EvaluateSubscriptIntExpr(const T &expr) { 207 if (MaybeIntExpr maybeIntExpr{EvaluateIntExpr(expr)}) { 208 return FoldExpr(evaluate::ConvertToType<evaluate::SubscriptInteger>( 209 std::move(*maybeIntExpr))); 210 } else { 211 return std::nullopt; 212 } 213 } 214 215 template <typename... A> Message &Say(A &&...args) { 216 return messageHandler_.Say(std::forward<A>(args)...); 217 } 218 template <typename... A> 219 Message &Say( 220 const parser::Name &name, MessageFixedText &&text, const A &...args) { 221 return messageHandler_.Say(name.source, std::move(text), args...); 222 } 223 224 protected: 225 ImplicitRulesMap *implicitRulesMap_{nullptr}; 226 227 private: 228 ResolveNamesVisitor *this_; 229 SemanticsContext *context_; 230 MessageHandler messageHandler_; 231 }; 232 233 // Provide Post methods to collect attributes into a member variable. 234 class AttrsVisitor : public virtual BaseVisitor { 235 public: 236 bool BeginAttrs(); // always returns true 237 Attrs GetAttrs(); 238 Attrs EndAttrs(); 239 bool SetPassNameOn(Symbol &); 240 void SetBindNameOn(Symbol &); 241 void Post(const parser::LanguageBindingSpec &); 242 bool Pre(const parser::IntentSpec &); 243 bool Pre(const parser::Pass &); 244 245 bool CheckAndSet(Attr); 246 247 // Simple case: encountering CLASSNAME causes ATTRNAME to be set. 248 #define HANDLE_ATTR_CLASS(CLASSNAME, ATTRNAME) \ 249 bool Pre(const parser::CLASSNAME &) { \ 250 CheckAndSet(Attr::ATTRNAME); \ 251 return false; \ 252 } 253 HANDLE_ATTR_CLASS(PrefixSpec::Elemental, ELEMENTAL) 254 HANDLE_ATTR_CLASS(PrefixSpec::Impure, IMPURE) 255 HANDLE_ATTR_CLASS(PrefixSpec::Module, MODULE) 256 HANDLE_ATTR_CLASS(PrefixSpec::Non_Recursive, NON_RECURSIVE) 257 HANDLE_ATTR_CLASS(PrefixSpec::Pure, PURE) 258 HANDLE_ATTR_CLASS(PrefixSpec::Recursive, RECURSIVE) 259 HANDLE_ATTR_CLASS(TypeAttrSpec::BindC, BIND_C) 260 HANDLE_ATTR_CLASS(BindAttr::Deferred, DEFERRED) 261 HANDLE_ATTR_CLASS(BindAttr::Non_Overridable, NON_OVERRIDABLE) 262 HANDLE_ATTR_CLASS(Abstract, ABSTRACT) 263 HANDLE_ATTR_CLASS(Allocatable, ALLOCATABLE) 264 HANDLE_ATTR_CLASS(Asynchronous, ASYNCHRONOUS) 265 HANDLE_ATTR_CLASS(Contiguous, CONTIGUOUS) 266 HANDLE_ATTR_CLASS(External, EXTERNAL) 267 HANDLE_ATTR_CLASS(Intrinsic, INTRINSIC) 268 HANDLE_ATTR_CLASS(NoPass, NOPASS) 269 HANDLE_ATTR_CLASS(Optional, OPTIONAL) 270 HANDLE_ATTR_CLASS(Parameter, PARAMETER) 271 HANDLE_ATTR_CLASS(Pointer, POINTER) 272 HANDLE_ATTR_CLASS(Protected, PROTECTED) 273 HANDLE_ATTR_CLASS(Save, SAVE) 274 HANDLE_ATTR_CLASS(Target, TARGET) 275 HANDLE_ATTR_CLASS(Value, VALUE) 276 HANDLE_ATTR_CLASS(Volatile, VOLATILE) 277 #undef HANDLE_ATTR_CLASS 278 279 protected: 280 std::optional<Attrs> attrs_; 281 282 Attr AccessSpecToAttr(const parser::AccessSpec &x) { 283 switch (x.v) { 284 case parser::AccessSpec::Kind::Public: 285 return Attr::PUBLIC; 286 case parser::AccessSpec::Kind::Private: 287 return Attr::PRIVATE; 288 } 289 llvm_unreachable("Switch covers all cases"); // suppress g++ warning 290 } 291 Attr IntentSpecToAttr(const parser::IntentSpec &x) { 292 switch (x.v) { 293 case parser::IntentSpec::Intent::In: 294 return Attr::INTENT_IN; 295 case parser::IntentSpec::Intent::Out: 296 return Attr::INTENT_OUT; 297 case parser::IntentSpec::Intent::InOut: 298 return Attr::INTENT_INOUT; 299 } 300 llvm_unreachable("Switch covers all cases"); // suppress g++ warning 301 } 302 303 private: 304 bool IsDuplicateAttr(Attr); 305 bool HaveAttrConflict(Attr, Attr, Attr); 306 bool IsConflictingAttr(Attr); 307 308 MaybeExpr bindName_; // from BIND(C, NAME="...") 309 std::optional<SourceName> passName_; // from PASS(...) 310 }; 311 312 // Find and create types from declaration-type-spec nodes. 313 class DeclTypeSpecVisitor : public AttrsVisitor { 314 public: 315 using AttrsVisitor::Post; 316 using AttrsVisitor::Pre; 317 void Post(const parser::IntrinsicTypeSpec::DoublePrecision &); 318 void Post(const parser::IntrinsicTypeSpec::DoubleComplex &); 319 void Post(const parser::DeclarationTypeSpec::ClassStar &); 320 void Post(const parser::DeclarationTypeSpec::TypeStar &); 321 bool Pre(const parser::TypeGuardStmt &); 322 void Post(const parser::TypeGuardStmt &); 323 void Post(const parser::TypeSpec &); 324 325 // Walk the parse tree of a type spec and return the DeclTypeSpec for it. 326 template <typename T> 327 const DeclTypeSpec *ProcessTypeSpec(const T &x, bool allowForward = false) { 328 auto restorer{common::ScopedSet(state_, State{})}; 329 set_allowForwardReferenceToDerivedType(allowForward); 330 BeginDeclTypeSpec(); 331 Walk(x); 332 const auto *type{GetDeclTypeSpec()}; 333 EndDeclTypeSpec(); 334 return type; 335 } 336 337 protected: 338 struct State { 339 bool expectDeclTypeSpec{false}; // should see decl-type-spec only when true 340 const DeclTypeSpec *declTypeSpec{nullptr}; 341 struct { 342 DerivedTypeSpec *type{nullptr}; 343 DeclTypeSpec::Category category{DeclTypeSpec::TypeDerived}; 344 } derived; 345 bool allowForwardReferenceToDerivedType{false}; 346 }; 347 348 bool allowForwardReferenceToDerivedType() const { 349 return state_.allowForwardReferenceToDerivedType; 350 } 351 void set_allowForwardReferenceToDerivedType(bool yes) { 352 state_.allowForwardReferenceToDerivedType = yes; 353 } 354 355 const DeclTypeSpec *GetDeclTypeSpec(); 356 void BeginDeclTypeSpec(); 357 void EndDeclTypeSpec(); 358 void SetDeclTypeSpec(const DeclTypeSpec &); 359 void SetDeclTypeSpecCategory(DeclTypeSpec::Category); 360 DeclTypeSpec::Category GetDeclTypeSpecCategory() const { 361 return state_.derived.category; 362 } 363 KindExpr GetKindParamExpr( 364 TypeCategory, const std::optional<parser::KindSelector> &); 365 void CheckForAbstractType(const Symbol &typeSymbol); 366 367 private: 368 State state_; 369 370 void MakeNumericType(TypeCategory, int kind); 371 }; 372 373 // Visit ImplicitStmt and related parse tree nodes and updates implicit rules. 374 class ImplicitRulesVisitor : public DeclTypeSpecVisitor { 375 public: 376 using DeclTypeSpecVisitor::Post; 377 using DeclTypeSpecVisitor::Pre; 378 using ImplicitNoneNameSpec = parser::ImplicitStmt::ImplicitNoneNameSpec; 379 380 void Post(const parser::ParameterStmt &); 381 bool Pre(const parser::ImplicitStmt &); 382 bool Pre(const parser::LetterSpec &); 383 bool Pre(const parser::ImplicitSpec &); 384 void Post(const parser::ImplicitSpec &); 385 386 const DeclTypeSpec *GetType( 387 SourceName name, bool respectImplicitNoneType = true) { 388 return implicitRules_->GetType(name, respectImplicitNoneType); 389 } 390 bool isImplicitNoneType() const { 391 return implicitRules_->isImplicitNoneType(); 392 } 393 bool isImplicitNoneType(const Scope &scope) const { 394 return implicitRulesMap_->at(&scope).isImplicitNoneType(); 395 } 396 bool isImplicitNoneExternal() const { 397 return implicitRules_->isImplicitNoneExternal(); 398 } 399 void set_inheritFromParent(bool x) { 400 implicitRules_->set_inheritFromParent(x); 401 } 402 403 protected: 404 void BeginScope(const Scope &); 405 void SetScope(const Scope &); 406 407 private: 408 // implicit rules in effect for current scope 409 ImplicitRules *implicitRules_{nullptr}; 410 std::optional<SourceName> prevImplicit_; 411 std::optional<SourceName> prevImplicitNone_; 412 std::optional<SourceName> prevImplicitNoneType_; 413 std::optional<SourceName> prevParameterStmt_; 414 415 bool HandleImplicitNone(const std::list<ImplicitNoneNameSpec> &nameSpecs); 416 }; 417 418 // Track array specifications. They can occur in AttrSpec, EntityDecl, 419 // ObjectDecl, DimensionStmt, CommonBlockObject, or BasedPointerStmt. 420 // 1. INTEGER, DIMENSION(10) :: x 421 // 2. INTEGER :: x(10) 422 // 3. ALLOCATABLE :: x(:) 423 // 4. DIMENSION :: x(10) 424 // 5. COMMON x(10) 425 // 6. BasedPointerStmt 426 class ArraySpecVisitor : public virtual BaseVisitor { 427 public: 428 void Post(const parser::ArraySpec &); 429 void Post(const parser::ComponentArraySpec &); 430 void Post(const parser::CoarraySpec &); 431 void Post(const parser::AttrSpec &) { PostAttrSpec(); } 432 void Post(const parser::ComponentAttrSpec &) { PostAttrSpec(); } 433 434 protected: 435 const ArraySpec &arraySpec(); 436 void set_arraySpec(const ArraySpec arraySpec) { arraySpec_ = arraySpec; } 437 const ArraySpec &coarraySpec(); 438 void BeginArraySpec(); 439 void EndArraySpec(); 440 void ClearArraySpec() { arraySpec_.clear(); } 441 void ClearCoarraySpec() { coarraySpec_.clear(); } 442 443 private: 444 // arraySpec_/coarraySpec_ are populated from any ArraySpec/CoarraySpec 445 ArraySpec arraySpec_; 446 ArraySpec coarraySpec_; 447 // When an ArraySpec is under an AttrSpec or ComponentAttrSpec, it is moved 448 // into attrArraySpec_ 449 ArraySpec attrArraySpec_; 450 ArraySpec attrCoarraySpec_; 451 452 void PostAttrSpec(); 453 }; 454 455 // Manages a stack of function result information. We defer the processing 456 // of a type specification that appears in the prefix of a FUNCTION statement 457 // until the function result variable appears in the specification part 458 // or the end of the specification part. This allows for forward references 459 // in the type specification to resolve to local names. 460 class FuncResultStack { 461 public: 462 explicit FuncResultStack(ScopeHandler &scopeHandler) 463 : scopeHandler_{scopeHandler} {} 464 ~FuncResultStack(); 465 466 struct FuncInfo { 467 // Parse tree of the type specification in the FUNCTION prefix 468 const parser::DeclarationTypeSpec *parsedType{nullptr}; 469 // Name of the function RESULT in the FUNCTION suffix, if any 470 const parser::Name *resultName{nullptr}; 471 // Result symbol 472 Symbol *resultSymbol{nullptr}; 473 std::optional<SourceName> source; 474 bool inFunctionStmt{false}; // true between Pre/Post of FunctionStmt 475 }; 476 477 // Completes the definition of the top function's result. 478 void CompleteFunctionResultType(); 479 // Completes the definition of a symbol if it is the top function's result. 480 void CompleteTypeIfFunctionResult(Symbol &); 481 482 FuncInfo *Top() { return stack_.empty() ? nullptr : &stack_.back(); } 483 FuncInfo &Push() { return stack_.emplace_back(); } 484 void Pop() { stack_.pop_back(); } 485 486 private: 487 ScopeHandler &scopeHandler_; 488 std::vector<FuncInfo> stack_; 489 }; 490 491 // Manage a stack of Scopes 492 class ScopeHandler : public ImplicitRulesVisitor { 493 public: 494 using ImplicitRulesVisitor::Post; 495 using ImplicitRulesVisitor::Pre; 496 497 Scope &currScope() { return DEREF(currScope_); } 498 // The enclosing host procedure if current scope is in an internal procedure 499 Scope *GetHostProcedure(); 500 // The innermost enclosing program unit scope, ignoring BLOCK and other 501 // construct scopes. 502 Scope &InclusiveScope(); 503 // The enclosing scope, skipping derived types. 504 Scope &NonDerivedTypeScope(); 505 506 // Create a new scope and push it on the scope stack. 507 void PushScope(Scope::Kind kind, Symbol *symbol); 508 void PushScope(Scope &scope); 509 void PopScope(); 510 void SetScope(Scope &); 511 512 template <typename T> bool Pre(const parser::Statement<T> &x) { 513 messageHandler().set_currStmtSource(x.source); 514 currScope_->AddSourceRange(x.source); 515 return true; 516 } 517 template <typename T> void Post(const parser::Statement<T> &) { 518 messageHandler().set_currStmtSource(std::nullopt); 519 } 520 521 // Special messages: already declared; referencing symbol's declaration; 522 // about a type; two names & locations 523 void SayAlreadyDeclared(const parser::Name &, Symbol &); 524 void SayAlreadyDeclared(const SourceName &, Symbol &); 525 void SayAlreadyDeclared(const SourceName &, const SourceName &); 526 void SayWithReason( 527 const parser::Name &, Symbol &, MessageFixedText &&, Message &&); 528 void SayWithDecl(const parser::Name &, Symbol &, MessageFixedText &&); 529 void SayLocalMustBeVariable(const parser::Name &, Symbol &); 530 void SayDerivedType(const SourceName &, MessageFixedText &&, const Scope &); 531 void Say2(const SourceName &, MessageFixedText &&, const SourceName &, 532 MessageFixedText &&); 533 void Say2( 534 const SourceName &, MessageFixedText &&, Symbol &, MessageFixedText &&); 535 void Say2( 536 const parser::Name &, MessageFixedText &&, Symbol &, MessageFixedText &&); 537 538 // Search for symbol by name in current, parent derived type, and 539 // containing scopes 540 Symbol *FindSymbol(const parser::Name &); 541 Symbol *FindSymbol(const Scope &, const parser::Name &); 542 // Search for name only in scope, not in enclosing scopes. 543 Symbol *FindInScope(const Scope &, const parser::Name &); 544 Symbol *FindInScope(const Scope &, const SourceName &); 545 template <typename T> Symbol *FindInScope(const T &name) { 546 return FindInScope(currScope(), name); 547 } 548 // Search for name in a derived type scope and its parents. 549 Symbol *FindInTypeOrParents(const Scope &, const parser::Name &); 550 Symbol *FindInTypeOrParents(const parser::Name &); 551 void EraseSymbol(const parser::Name &); 552 void EraseSymbol(const Symbol &symbol) { currScope().erase(symbol.name()); } 553 // Make a new symbol with the name and attrs of an existing one 554 Symbol &CopySymbol(const SourceName &, const Symbol &); 555 556 // Make symbols in the current or named scope 557 Symbol &MakeSymbol(Scope &, const SourceName &, Attrs); 558 Symbol &MakeSymbol(const SourceName &, Attrs = Attrs{}); 559 Symbol &MakeSymbol(const parser::Name &, Attrs = Attrs{}); 560 Symbol &MakeHostAssocSymbol(const parser::Name &, const Symbol &); 561 562 template <typename D> 563 common::IfNoLvalue<Symbol &, D> MakeSymbol( 564 const parser::Name &name, D &&details) { 565 return MakeSymbol(name, Attrs{}, std::move(details)); 566 } 567 568 template <typename D> 569 common::IfNoLvalue<Symbol &, D> MakeSymbol( 570 const parser::Name &name, const Attrs &attrs, D &&details) { 571 return Resolve(name, MakeSymbol(name.source, attrs, std::move(details))); 572 } 573 574 template <typename D> 575 common::IfNoLvalue<Symbol &, D> MakeSymbol( 576 const SourceName &name, const Attrs &attrs, D &&details) { 577 // Note: don't use FindSymbol here. If this is a derived type scope, 578 // we want to detect whether the name is already declared as a component. 579 auto *symbol{FindInScope(name)}; 580 if (!symbol) { 581 symbol = &MakeSymbol(name, attrs); 582 symbol->set_details(std::move(details)); 583 return *symbol; 584 } 585 if constexpr (std::is_same_v<DerivedTypeDetails, D>) { 586 if (auto *d{symbol->detailsIf<GenericDetails>()}) { 587 if (!d->specific()) { 588 // derived type with same name as a generic 589 auto *derivedType{d->derivedType()}; 590 if (!derivedType) { 591 derivedType = 592 &currScope().MakeSymbol(name, attrs, std::move(details)); 593 d->set_derivedType(*derivedType); 594 } else { 595 SayAlreadyDeclared(name, *derivedType); 596 } 597 return *derivedType; 598 } 599 } 600 } 601 if (symbol->CanReplaceDetails(details)) { 602 // update the existing symbol 603 symbol->attrs() |= attrs; 604 if constexpr (std::is_same_v<SubprogramDetails, D>) { 605 // Dummy argument defined by explicit interface 606 details.set_isDummy(IsDummy(*symbol)); 607 } 608 symbol->set_details(std::move(details)); 609 return *symbol; 610 } else if constexpr (std::is_same_v<UnknownDetails, D>) { 611 symbol->attrs() |= attrs; 612 return *symbol; 613 } else { 614 if (!CheckPossibleBadForwardRef(*symbol)) { 615 SayAlreadyDeclared(name, *symbol); 616 } 617 // replace the old symbol with a new one with correct details 618 EraseSymbol(*symbol); 619 auto &result{MakeSymbol(name, attrs, std::move(details))}; 620 context().SetError(result); 621 return result; 622 } 623 } 624 625 void MakeExternal(Symbol &); 626 627 protected: 628 FuncResultStack &funcResultStack() { return funcResultStack_; } 629 630 // Apply the implicit type rules to this symbol. 631 void ApplyImplicitRules(Symbol &, bool allowForwardReference = false); 632 bool ImplicitlyTypeForwardRef(Symbol &); 633 void AcquireIntrinsicProcedureFlags(Symbol &); 634 const DeclTypeSpec *GetImplicitType( 635 Symbol &, bool respectImplicitNoneType = true); 636 bool ConvertToObjectEntity(Symbol &); 637 bool ConvertToProcEntity(Symbol &); 638 639 const DeclTypeSpec &MakeNumericType( 640 TypeCategory, const std::optional<parser::KindSelector> &); 641 const DeclTypeSpec &MakeLogicalType( 642 const std::optional<parser::KindSelector> &); 643 void NotePossibleBadForwardRef(const parser::Name &); 644 std::optional<SourceName> HadForwardRef(const Symbol &) const; 645 bool CheckPossibleBadForwardRef(const Symbol &); 646 647 bool inExecutionPart_{false}; 648 bool inSpecificationPart_{false}; 649 bool inEquivalenceStmt_{false}; 650 651 // Some information is collected from a specification part for deferred 652 // processing in DeclarationPartVisitor functions (e.g., CheckSaveStmts()) 653 // that are called by ResolveNamesVisitor::FinishSpecificationPart(). Since 654 // specification parts can nest (e.g., INTERFACE bodies), the collected 655 // information that is not contained in the scope needs to be packaged 656 // and restorable. 657 struct SpecificationPartState { 658 std::set<SourceName> forwardRefs; 659 // Collect equivalence sets and process at end of specification part 660 std::vector<const std::list<parser::EquivalenceObject> *> equivalenceSets; 661 // Names of all common block objects in the scope 662 std::set<SourceName> commonBlockObjects; 663 // Info about about SAVE statements and attributes in current scope 664 struct { 665 std::optional<SourceName> saveAll; // "SAVE" without entity list 666 std::set<SourceName> entities; // names of entities with save attr 667 std::set<SourceName> commons; // names of common blocks with save attr 668 } saveInfo; 669 } specPartState_; 670 671 // Some declaration processing can and should be deferred to 672 // ResolveExecutionParts() to avoid prematurely creating implicitly-typed 673 // local symbols that should be host associations. 674 struct DeferredDeclarationState { 675 // The content of each namelist group 676 std::list<const parser::NamelistStmt::Group *> namelistGroups; 677 }; 678 DeferredDeclarationState *GetDeferredDeclarationState(bool add = false) { 679 if (!add && deferred_.find(&currScope()) == deferred_.end()) { 680 return nullptr; 681 } else { 682 return &deferred_.emplace(&currScope(), DeferredDeclarationState{}) 683 .first->second; 684 } 685 } 686 687 private: 688 Scope *currScope_{nullptr}; 689 FuncResultStack funcResultStack_{*this}; 690 std::map<Scope *, DeferredDeclarationState> deferred_; 691 }; 692 693 class ModuleVisitor : public virtual ScopeHandler { 694 public: 695 bool Pre(const parser::AccessStmt &); 696 bool Pre(const parser::Only &); 697 bool Pre(const parser::Rename::Names &); 698 bool Pre(const parser::Rename::Operators &); 699 bool Pre(const parser::UseStmt &); 700 void Post(const parser::UseStmt &); 701 702 void BeginModule(const parser::Name &, bool isSubmodule); 703 bool BeginSubmodule(const parser::Name &, const parser::ParentIdentifier &); 704 void ApplyDefaultAccess(); 705 Symbol &AddGenericUse(GenericDetails &, const SourceName &, const Symbol &); 706 void AddAndCheckExplicitIntrinsicUse(SourceName, bool isIntrinsic); 707 void ClearUseRenames() { useRenames_.clear(); } 708 void ClearUseOnly() { useOnly_.clear(); } 709 void ClearExplicitIntrinsicUses() { 710 explicitIntrinsicUses_.clear(); 711 explicitNonIntrinsicUses_.clear(); 712 } 713 714 private: 715 // The default access spec for this module. 716 Attr defaultAccess_{Attr::PUBLIC}; 717 // The location of the last AccessStmt without access-ids, if any. 718 std::optional<SourceName> prevAccessStmt_; 719 // The scope of the module during a UseStmt 720 Scope *useModuleScope_{nullptr}; 721 // Names that have appeared in a rename clause of a USE statement 722 std::set<std::pair<SourceName, Scope *>> useRenames_; 723 // Names that have appeared in an ONLY clause of a USE statement 724 std::set<std::pair<SourceName, Scope *>> useOnly_; 725 // Module names that have appeared in USE statements with explicit 726 // INTRINSIC or NON_INTRINSIC keywords 727 std::set<SourceName> explicitIntrinsicUses_; 728 std::set<SourceName> explicitNonIntrinsicUses_; 729 730 Symbol &SetAccess(const SourceName &, Attr attr, Symbol * = nullptr); 731 // A rename in a USE statement: local => use 732 struct SymbolRename { 733 Symbol *local{nullptr}; 734 Symbol *use{nullptr}; 735 }; 736 // Record a use from useModuleScope_ of use Name/Symbol as local Name/Symbol 737 SymbolRename AddUse(const SourceName &localName, const SourceName &useName); 738 SymbolRename AddUse(const SourceName &, const SourceName &, Symbol *); 739 void DoAddUse( 740 SourceName, SourceName, Symbol &localSymbol, const Symbol &useSymbol); 741 void AddUse(const GenericSpecInfo &); 742 // If appropriate, erase a previously USE-associated symbol 743 void EraseRenamedSymbol(const Symbol &); 744 // Record a name appearing in a USE rename clause 745 void AddUseRename(const SourceName &name) { 746 useRenames_.emplace(std::make_pair(name, useModuleScope_)); 747 } 748 bool IsUseRenamed(const SourceName &name) const { 749 return useRenames_.find({name, useModuleScope_}) != useRenames_.end(); 750 } 751 // Record a name appearing in a USE ONLY clause 752 void AddUseOnly(const SourceName &name) { 753 useOnly_.emplace(std::make_pair(name, useModuleScope_)); 754 } 755 bool IsUseOnly(const SourceName &name) const { 756 return useOnly_.find({name, useModuleScope_}) != useOnly_.end(); 757 } 758 Scope *FindModule(const parser::Name &, std::optional<bool> isIntrinsic, 759 Scope *ancestor = nullptr); 760 }; 761 762 class InterfaceVisitor : public virtual ScopeHandler { 763 public: 764 bool Pre(const parser::InterfaceStmt &); 765 void Post(const parser::InterfaceStmt &); 766 void Post(const parser::EndInterfaceStmt &); 767 bool Pre(const parser::GenericSpec &); 768 bool Pre(const parser::ProcedureStmt &); 769 bool Pre(const parser::GenericStmt &); 770 void Post(const parser::GenericStmt &); 771 772 bool inInterfaceBlock() const; 773 bool isGeneric() const; 774 bool isAbstract() const; 775 776 protected: 777 Symbol &GetGenericSymbol() { 778 return DEREF(genericInfo_.top().symbol); 779 } 780 // Add to generic the symbol for the subprogram with the same name 781 void CheckGenericProcedures(Symbol &); 782 783 private: 784 // A new GenericInfo is pushed for each interface block and generic stmt 785 struct GenericInfo { 786 GenericInfo(bool isInterface, bool isAbstract = false) 787 : isInterface{isInterface}, isAbstract{isAbstract} {} 788 bool isInterface; // in interface block 789 bool isAbstract; // in abstract interface block 790 Symbol *symbol{nullptr}; // the generic symbol being defined 791 }; 792 std::stack<GenericInfo> genericInfo_; 793 const GenericInfo &GetGenericInfo() const { return genericInfo_.top(); } 794 void SetGenericSymbol(Symbol &symbol) { genericInfo_.top().symbol = &symbol; } 795 796 using ProcedureKind = parser::ProcedureStmt::Kind; 797 // mapping of generic to its specific proc names and kinds 798 std::multimap<Symbol *, std::pair<const parser::Name *, ProcedureKind>> 799 specificProcs_; 800 801 void AddSpecificProcs(const std::list<parser::Name> &, ProcedureKind); 802 void ResolveSpecificsInGeneric(Symbol &generic); 803 }; 804 805 class SubprogramVisitor : public virtual ScopeHandler, public InterfaceVisitor { 806 public: 807 bool HandleStmtFunction(const parser::StmtFunctionStmt &); 808 bool Pre(const parser::SubroutineStmt &); 809 void Post(const parser::SubroutineStmt &); 810 bool Pre(const parser::FunctionStmt &); 811 void Post(const parser::FunctionStmt &); 812 bool Pre(const parser::EntryStmt &); 813 void Post(const parser::EntryStmt &); 814 bool Pre(const parser::InterfaceBody::Subroutine &); 815 void Post(const parser::InterfaceBody::Subroutine &); 816 bool Pre(const parser::InterfaceBody::Function &); 817 void Post(const parser::InterfaceBody::Function &); 818 bool Pre(const parser::Suffix &); 819 bool Pre(const parser::PrefixSpec &); 820 821 bool BeginSubprogram( 822 const parser::Name &, Symbol::Flag, bool hasModulePrefix = false); 823 bool BeginMpSubprogram(const parser::Name &); 824 void PushBlockDataScope(const parser::Name &); 825 void EndSubprogram(); 826 827 protected: 828 // Set when we see a stmt function that is really an array element assignment 829 bool badStmtFuncFound_{false}; 830 831 private: 832 // Edits an existing symbol created for earlier calls to a subprogram or ENTRY 833 // so that it can be replaced by a later definition. 834 bool HandlePreviousCalls(const parser::Name &, Symbol &, Symbol::Flag); 835 void CheckExtantProc(const parser::Name &, Symbol::Flag); 836 // Create a subprogram symbol in the current scope and push a new scope. 837 Symbol &PushSubprogramScope(const parser::Name &, Symbol::Flag); 838 Symbol *GetSpecificFromGeneric(const parser::Name &); 839 SubprogramDetails &PostSubprogramStmt(const parser::Name &); 840 }; 841 842 class DeclarationVisitor : public ArraySpecVisitor, 843 public virtual ScopeHandler { 844 public: 845 using ArraySpecVisitor::Post; 846 using ScopeHandler::Post; 847 using ScopeHandler::Pre; 848 849 bool Pre(const parser::Initialization &); 850 void Post(const parser::EntityDecl &); 851 void Post(const parser::ObjectDecl &); 852 void Post(const parser::PointerDecl &); 853 bool Pre(const parser::BindStmt &) { return BeginAttrs(); } 854 void Post(const parser::BindStmt &) { EndAttrs(); } 855 bool Pre(const parser::BindEntity &); 856 bool Pre(const parser::OldParameterStmt &); 857 bool Pre(const parser::NamedConstantDef &); 858 bool Pre(const parser::NamedConstant &); 859 void Post(const parser::EnumDef &); 860 bool Pre(const parser::Enumerator &); 861 bool Pre(const parser::AccessSpec &); 862 bool Pre(const parser::AsynchronousStmt &); 863 bool Pre(const parser::ContiguousStmt &); 864 bool Pre(const parser::ExternalStmt &); 865 bool Pre(const parser::IntentStmt &); 866 bool Pre(const parser::IntrinsicStmt &); 867 bool Pre(const parser::OptionalStmt &); 868 bool Pre(const parser::ProtectedStmt &); 869 bool Pre(const parser::ValueStmt &); 870 bool Pre(const parser::VolatileStmt &); 871 bool Pre(const parser::AllocatableStmt &) { 872 objectDeclAttr_ = Attr::ALLOCATABLE; 873 return true; 874 } 875 void Post(const parser::AllocatableStmt &) { objectDeclAttr_ = std::nullopt; } 876 bool Pre(const parser::TargetStmt &) { 877 objectDeclAttr_ = Attr::TARGET; 878 return true; 879 } 880 void Post(const parser::TargetStmt &) { objectDeclAttr_ = std::nullopt; } 881 void Post(const parser::DimensionStmt::Declaration &); 882 void Post(const parser::CodimensionDecl &); 883 bool Pre(const parser::TypeDeclarationStmt &) { return BeginDecl(); } 884 void Post(const parser::TypeDeclarationStmt &); 885 void Post(const parser::IntegerTypeSpec &); 886 void Post(const parser::IntrinsicTypeSpec::Real &); 887 void Post(const parser::IntrinsicTypeSpec::Complex &); 888 void Post(const parser::IntrinsicTypeSpec::Logical &); 889 void Post(const parser::IntrinsicTypeSpec::Character &); 890 void Post(const parser::CharSelector::LengthAndKind &); 891 void Post(const parser::CharLength &); 892 void Post(const parser::LengthSelector &); 893 bool Pre(const parser::KindParam &); 894 bool Pre(const parser::DeclarationTypeSpec::Type &); 895 void Post(const parser::DeclarationTypeSpec::Type &); 896 bool Pre(const parser::DeclarationTypeSpec::Class &); 897 void Post(const parser::DeclarationTypeSpec::Class &); 898 void Post(const parser::DeclarationTypeSpec::Record &); 899 void Post(const parser::DerivedTypeSpec &); 900 bool Pre(const parser::DerivedTypeDef &); 901 bool Pre(const parser::DerivedTypeStmt &); 902 void Post(const parser::DerivedTypeStmt &); 903 bool Pre(const parser::TypeParamDefStmt &) { return BeginDecl(); } 904 void Post(const parser::TypeParamDefStmt &); 905 bool Pre(const parser::TypeAttrSpec::Extends &); 906 bool Pre(const parser::PrivateStmt &); 907 bool Pre(const parser::SequenceStmt &); 908 bool Pre(const parser::ComponentDefStmt &) { return BeginDecl(); } 909 void Post(const parser::ComponentDefStmt &) { EndDecl(); } 910 void Post(const parser::ComponentDecl &); 911 void Post(const parser::FillDecl &); 912 bool Pre(const parser::ProcedureDeclarationStmt &); 913 void Post(const parser::ProcedureDeclarationStmt &); 914 bool Pre(const parser::DataComponentDefStmt &); // returns false 915 bool Pre(const parser::ProcComponentDefStmt &); 916 void Post(const parser::ProcComponentDefStmt &); 917 bool Pre(const parser::ProcPointerInit &); 918 void Post(const parser::ProcInterface &); 919 void Post(const parser::ProcDecl &); 920 bool Pre(const parser::TypeBoundProcedurePart &); 921 void Post(const parser::TypeBoundProcedurePart &); 922 void Post(const parser::ContainsStmt &); 923 bool Pre(const parser::TypeBoundProcBinding &) { return BeginAttrs(); } 924 void Post(const parser::TypeBoundProcBinding &) { EndAttrs(); } 925 void Post(const parser::TypeBoundProcedureStmt::WithoutInterface &); 926 void Post(const parser::TypeBoundProcedureStmt::WithInterface &); 927 void Post(const parser::FinalProcedureStmt &); 928 bool Pre(const parser::TypeBoundGenericStmt &); 929 bool Pre(const parser::StructureDef &); // returns false 930 bool Pre(const parser::Union::UnionStmt &); 931 bool Pre(const parser::StructureField &); 932 void Post(const parser::StructureField &); 933 bool Pre(const parser::AllocateStmt &); 934 void Post(const parser::AllocateStmt &); 935 bool Pre(const parser::StructureConstructor &); 936 bool Pre(const parser::NamelistStmt::Group &); 937 bool Pre(const parser::IoControlSpec &); 938 bool Pre(const parser::CommonStmt::Block &); 939 bool Pre(const parser::CommonBlockObject &); 940 void Post(const parser::CommonBlockObject &); 941 bool Pre(const parser::EquivalenceStmt &); 942 bool Pre(const parser::SaveStmt &); 943 bool Pre(const parser::BasedPointerStmt &); 944 945 void PointerInitialization( 946 const parser::Name &, const parser::InitialDataTarget &); 947 void PointerInitialization( 948 const parser::Name &, const parser::ProcPointerInit &); 949 void NonPointerInitialization( 950 const parser::Name &, const parser::ConstantExpr &); 951 void CheckExplicitInterface(const parser::Name &); 952 void CheckBindings(const parser::TypeBoundProcedureStmt::WithoutInterface &); 953 954 const parser::Name *ResolveDesignator(const parser::Designator &); 955 956 protected: 957 bool BeginDecl(); 958 void EndDecl(); 959 Symbol &DeclareObjectEntity(const parser::Name &, Attrs = Attrs{}); 960 // Make sure that there's an entity in an enclosing scope called Name 961 Symbol &FindOrDeclareEnclosingEntity(const parser::Name &); 962 // Declare a LOCAL/LOCAL_INIT entity. If there isn't a type specified 963 // it comes from the entity in the containing scope, or implicit rules. 964 // Return pointer to the new symbol, or nullptr on error. 965 Symbol *DeclareLocalEntity(const parser::Name &); 966 // Declare a statement entity (i.e., an implied DO loop index for 967 // a DATA statement or an array constructor). If there isn't an explict 968 // type specified, implicit rules apply. Return pointer to the new symbol, 969 // or nullptr on error. 970 Symbol *DeclareStatementEntity(const parser::DoVariable &, 971 const std::optional<parser::IntegerTypeSpec> &); 972 Symbol &MakeCommonBlockSymbol(const parser::Name &); 973 Symbol &MakeCommonBlockSymbol(const std::optional<parser::Name> &); 974 bool CheckUseError(const parser::Name &); 975 void CheckAccessibility(const SourceName &, bool, Symbol &); 976 void CheckCommonBlocks(); 977 void CheckSaveStmts(); 978 void CheckEquivalenceSets(); 979 bool CheckNotInBlock(const char *); 980 bool NameIsKnownOrIntrinsic(const parser::Name &); 981 void FinishNamelists(); 982 983 // Each of these returns a pointer to a resolved Name (i.e. with symbol) 984 // or nullptr in case of error. 985 const parser::Name *ResolveStructureComponent( 986 const parser::StructureComponent &); 987 const parser::Name *ResolveDataRef(const parser::DataRef &); 988 const parser::Name *ResolveName(const parser::Name &); 989 bool PassesSharedLocalityChecks(const parser::Name &name, Symbol &symbol); 990 Symbol *NoteInterfaceName(const parser::Name &); 991 bool IsUplevelReference(const Symbol &); 992 993 std::optional<SourceName> BeginCheckOnIndexUseInOwnBounds( 994 const parser::DoVariable &name) { 995 std::optional<SourceName> result{checkIndexUseInOwnBounds_}; 996 checkIndexUseInOwnBounds_ = name.thing.thing.source; 997 return result; 998 } 999 void EndCheckOnIndexUseInOwnBounds(const std::optional<SourceName> &restore) { 1000 checkIndexUseInOwnBounds_ = restore; 1001 } 1002 1003 private: 1004 // The attribute corresponding to the statement containing an ObjectDecl 1005 std::optional<Attr> objectDeclAttr_; 1006 // Info about current character type while walking DeclTypeSpec. 1007 // Also captures any "*length" specifier on an individual declaration. 1008 struct { 1009 std::optional<ParamValue> length; 1010 std::optional<KindExpr> kind; 1011 } charInfo_; 1012 // Info about current derived type or STRUCTURE while walking 1013 // DerivedTypeDef / StructureDef 1014 struct { 1015 const parser::Name *extends{nullptr}; // EXTENDS(name) 1016 bool privateComps{false}; // components are private by default 1017 bool privateBindings{false}; // bindings are private by default 1018 bool sawContains{false}; // currently processing bindings 1019 bool sequence{false}; // is a sequence type 1020 const Symbol *type{nullptr}; // derived type being defined 1021 bool isStructure{false}; // is a DEC STRUCTURE 1022 } derivedTypeInfo_; 1023 // In a ProcedureDeclarationStmt or ProcComponentDefStmt, this is 1024 // the interface name, if any. 1025 const parser::Name *interfaceName_{nullptr}; 1026 // Map type-bound generic to binding names of its specific bindings 1027 std::multimap<Symbol *, const parser::Name *> genericBindings_; 1028 // Info about current ENUM 1029 struct EnumeratorState { 1030 // Enum value must hold inside a C_INT (7.6.2). 1031 std::optional<int> value{0}; 1032 } enumerationState_; 1033 // Set for OldParameterStmt processing 1034 bool inOldStyleParameterStmt_{false}; 1035 // Set when walking DATA & array constructor implied DO loop bounds 1036 // to warn about use of the implied DO intex therein. 1037 std::optional<SourceName> checkIndexUseInOwnBounds_; 1038 1039 bool HandleAttributeStmt(Attr, const std::list<parser::Name> &); 1040 Symbol &HandleAttributeStmt(Attr, const parser::Name &); 1041 Symbol &DeclareUnknownEntity(const parser::Name &, Attrs); 1042 Symbol &DeclareProcEntity(const parser::Name &, Attrs, const ProcInterface &); 1043 void SetType(const parser::Name &, const DeclTypeSpec &); 1044 std::optional<DerivedTypeSpec> ResolveDerivedType(const parser::Name &); 1045 std::optional<DerivedTypeSpec> ResolveExtendsType( 1046 const parser::Name &, const parser::Name *); 1047 Symbol *MakeTypeSymbol(const SourceName &, Details &&); 1048 Symbol *MakeTypeSymbol(const parser::Name &, Details &&); 1049 bool OkToAddComponent(const parser::Name &, const Symbol * = nullptr); 1050 ParamValue GetParamValue( 1051 const parser::TypeParamValue &, common::TypeParamAttr attr); 1052 void CheckCommonBlockDerivedType(const SourceName &, const Symbol &); 1053 std::optional<MessageFixedText> CheckSaveAttr(const Symbol &); 1054 Attrs HandleSaveName(const SourceName &, Attrs); 1055 void AddSaveName(std::set<SourceName> &, const SourceName &); 1056 void SetSaveAttr(Symbol &); 1057 bool HandleUnrestrictedSpecificIntrinsicFunction(const parser::Name &); 1058 const parser::Name *FindComponent(const parser::Name *, const parser::Name &); 1059 void Initialization(const parser::Name &, const parser::Initialization &, 1060 bool inComponentDecl); 1061 bool PassesLocalityChecks(const parser::Name &name, Symbol &symbol); 1062 bool CheckForHostAssociatedImplicit(const parser::Name &); 1063 1064 // Declare an object or procedure entity. 1065 // T is one of: EntityDetails, ObjectEntityDetails, ProcEntityDetails 1066 template <typename T> 1067 Symbol &DeclareEntity(const parser::Name &name, Attrs attrs) { 1068 Symbol &symbol{MakeSymbol(name, attrs)}; 1069 if (context().HasError(symbol) || symbol.has<T>()) { 1070 return symbol; // OK or error already reported 1071 } else if (symbol.has<UnknownDetails>()) { 1072 symbol.set_details(T{}); 1073 return symbol; 1074 } else if (auto *details{symbol.detailsIf<EntityDetails>()}) { 1075 symbol.set_details(T{std::move(*details)}); 1076 return symbol; 1077 } else if (std::is_same_v<EntityDetails, T> && 1078 (symbol.has<ObjectEntityDetails>() || 1079 symbol.has<ProcEntityDetails>())) { 1080 return symbol; // OK 1081 } else if (auto *details{symbol.detailsIf<UseDetails>()}) { 1082 Say(name.source, 1083 "'%s' is use-associated from module '%s' and cannot be re-declared"_err_en_US, 1084 name.source, GetUsedModule(*details).name()); 1085 } else if (auto *details{symbol.detailsIf<SubprogramNameDetails>()}) { 1086 if (details->kind() == SubprogramKind::Module) { 1087 Say2(name, 1088 "Declaration of '%s' conflicts with its use as module procedure"_err_en_US, 1089 symbol, "Module procedure definition"_en_US); 1090 } else if (details->kind() == SubprogramKind::Internal) { 1091 Say2(name, 1092 "Declaration of '%s' conflicts with its use as internal procedure"_err_en_US, 1093 symbol, "Internal procedure definition"_en_US); 1094 } else { 1095 DIE("unexpected kind"); 1096 } 1097 } else if (std::is_same_v<ObjectEntityDetails, T> && 1098 symbol.has<ProcEntityDetails>()) { 1099 SayWithDecl( 1100 name, symbol, "'%s' is already declared as a procedure"_err_en_US); 1101 } else if (std::is_same_v<ProcEntityDetails, T> && 1102 symbol.has<ObjectEntityDetails>()) { 1103 if (InCommonBlock(symbol)) { 1104 SayWithDecl(name, symbol, 1105 "'%s' may not be a procedure as it is in a COMMON block"_err_en_US); 1106 } else { 1107 SayWithDecl( 1108 name, symbol, "'%s' is already declared as an object"_err_en_US); 1109 } 1110 } else if (!CheckPossibleBadForwardRef(symbol)) { 1111 SayAlreadyDeclared(name, symbol); 1112 } 1113 context().SetError(symbol); 1114 return symbol; 1115 } 1116 bool HasCycle(const Symbol &, const ProcInterface &); 1117 }; 1118 1119 // Resolve construct entities and statement entities. 1120 // Check that construct names don't conflict with other names. 1121 class ConstructVisitor : public virtual DeclarationVisitor { 1122 public: 1123 bool Pre(const parser::ConcurrentHeader &); 1124 bool Pre(const parser::LocalitySpec::Local &); 1125 bool Pre(const parser::LocalitySpec::LocalInit &); 1126 bool Pre(const parser::LocalitySpec::Shared &); 1127 bool Pre(const parser::AcSpec &); 1128 bool Pre(const parser::AcImpliedDo &); 1129 bool Pre(const parser::DataImpliedDo &); 1130 bool Pre(const parser::DataIDoObject &); 1131 bool Pre(const parser::DataStmtObject &); 1132 bool Pre(const parser::DataStmtValue &); 1133 bool Pre(const parser::DoConstruct &); 1134 void Post(const parser::DoConstruct &); 1135 bool Pre(const parser::ForallConstruct &); 1136 void Post(const parser::ForallConstruct &); 1137 bool Pre(const parser::ForallStmt &); 1138 void Post(const parser::ForallStmt &); 1139 bool Pre(const parser::BlockStmt &); 1140 bool Pre(const parser::EndBlockStmt &); 1141 void Post(const parser::Selector &); 1142 void Post(const parser::AssociateStmt &); 1143 void Post(const parser::EndAssociateStmt &); 1144 bool Pre(const parser::Association &); 1145 void Post(const parser::SelectTypeStmt &); 1146 void Post(const parser::SelectRankStmt &); 1147 bool Pre(const parser::SelectTypeConstruct &); 1148 void Post(const parser::SelectTypeConstruct &); 1149 bool Pre(const parser::SelectTypeConstruct::TypeCase &); 1150 void Post(const parser::SelectTypeConstruct::TypeCase &); 1151 // Creates Block scopes with neither symbol name nor symbol details. 1152 bool Pre(const parser::SelectRankConstruct::RankCase &); 1153 void Post(const parser::SelectRankConstruct::RankCase &); 1154 void Post(const parser::TypeGuardStmt::Guard &); 1155 void Post(const parser::SelectRankCaseStmt::Rank &); 1156 bool Pre(const parser::ChangeTeamStmt &); 1157 void Post(const parser::EndChangeTeamStmt &); 1158 void Post(const parser::CoarrayAssociation &); 1159 1160 // Definitions of construct names 1161 bool Pre(const parser::WhereConstructStmt &x) { return CheckDef(x.t); } 1162 bool Pre(const parser::ForallConstructStmt &x) { return CheckDef(x.t); } 1163 bool Pre(const parser::CriticalStmt &x) { return CheckDef(x.t); } 1164 bool Pre(const parser::LabelDoStmt &) { 1165 return false; // error recovery 1166 } 1167 bool Pre(const parser::NonLabelDoStmt &x) { return CheckDef(x.t); } 1168 bool Pre(const parser::IfThenStmt &x) { return CheckDef(x.t); } 1169 bool Pre(const parser::SelectCaseStmt &x) { return CheckDef(x.t); } 1170 bool Pre(const parser::SelectRankConstruct &); 1171 void Post(const parser::SelectRankConstruct &); 1172 bool Pre(const parser::SelectRankStmt &x) { 1173 return CheckDef(std::get<0>(x.t)); 1174 } 1175 bool Pre(const parser::SelectTypeStmt &x) { 1176 return CheckDef(std::get<0>(x.t)); 1177 } 1178 1179 // References to construct names 1180 void Post(const parser::MaskedElsewhereStmt &x) { CheckRef(x.t); } 1181 void Post(const parser::ElsewhereStmt &x) { CheckRef(x.v); } 1182 void Post(const parser::EndWhereStmt &x) { CheckRef(x.v); } 1183 void Post(const parser::EndForallStmt &x) { CheckRef(x.v); } 1184 void Post(const parser::EndCriticalStmt &x) { CheckRef(x.v); } 1185 void Post(const parser::EndDoStmt &x) { CheckRef(x.v); } 1186 void Post(const parser::ElseIfStmt &x) { CheckRef(x.t); } 1187 void Post(const parser::ElseStmt &x) { CheckRef(x.v); } 1188 void Post(const parser::EndIfStmt &x) { CheckRef(x.v); } 1189 void Post(const parser::CaseStmt &x) { CheckRef(x.t); } 1190 void Post(const parser::EndSelectStmt &x) { CheckRef(x.v); } 1191 void Post(const parser::SelectRankCaseStmt &x) { CheckRef(x.t); } 1192 void Post(const parser::TypeGuardStmt &x) { CheckRef(x.t); } 1193 void Post(const parser::CycleStmt &x) { CheckRef(x.v); } 1194 void Post(const parser::ExitStmt &x) { CheckRef(x.v); } 1195 1196 private: 1197 // R1105 selector -> expr | variable 1198 // expr is set in either case unless there were errors 1199 struct Selector { 1200 Selector() {} 1201 Selector(const SourceName &source, MaybeExpr &&expr) 1202 : source{source}, expr{std::move(expr)} {} 1203 operator bool() const { return expr.has_value(); } 1204 parser::CharBlock source; 1205 MaybeExpr expr; 1206 }; 1207 // association -> [associate-name =>] selector 1208 struct Association { 1209 const parser::Name *name{nullptr}; 1210 Selector selector; 1211 }; 1212 std::vector<Association> associationStack_; 1213 Association *currentAssociation_{nullptr}; 1214 1215 template <typename T> bool CheckDef(const T &t) { 1216 return CheckDef(std::get<std::optional<parser::Name>>(t)); 1217 } 1218 template <typename T> void CheckRef(const T &t) { 1219 CheckRef(std::get<std::optional<parser::Name>>(t)); 1220 } 1221 bool CheckDef(const std::optional<parser::Name> &); 1222 void CheckRef(const std::optional<parser::Name> &); 1223 const DeclTypeSpec &ToDeclTypeSpec(evaluate::DynamicType &&); 1224 const DeclTypeSpec &ToDeclTypeSpec( 1225 evaluate::DynamicType &&, MaybeSubscriptIntExpr &&length); 1226 Symbol *MakeAssocEntity(); 1227 void SetTypeFromAssociation(Symbol &); 1228 void SetAttrsFromAssociation(Symbol &); 1229 Selector ResolveSelector(const parser::Selector &); 1230 void ResolveIndexName(const parser::ConcurrentControl &control); 1231 void SetCurrentAssociation(std::size_t n); 1232 Association &GetCurrentAssociation(); 1233 void PushAssociation(); 1234 void PopAssociation(std::size_t count = 1); 1235 }; 1236 1237 // Create scopes for OpenACC constructs 1238 class AccVisitor : public virtual DeclarationVisitor { 1239 public: 1240 void AddAccSourceRange(const parser::CharBlock &); 1241 1242 static bool NeedsScope(const parser::OpenACCBlockConstruct &); 1243 1244 bool Pre(const parser::OpenACCBlockConstruct &); 1245 void Post(const parser::OpenACCBlockConstruct &); 1246 bool Pre(const parser::AccBeginBlockDirective &x) { 1247 AddAccSourceRange(x.source); 1248 return true; 1249 } 1250 void Post(const parser::AccBeginBlockDirective &) { 1251 messageHandler().set_currStmtSource(std::nullopt); 1252 } 1253 bool Pre(const parser::AccEndBlockDirective &x) { 1254 AddAccSourceRange(x.source); 1255 return true; 1256 } 1257 void Post(const parser::AccEndBlockDirective &) { 1258 messageHandler().set_currStmtSource(std::nullopt); 1259 } 1260 bool Pre(const parser::AccBeginLoopDirective &x) { 1261 AddAccSourceRange(x.source); 1262 return true; 1263 } 1264 void Post(const parser::AccBeginLoopDirective &x) { 1265 messageHandler().set_currStmtSource(std::nullopt); 1266 } 1267 }; 1268 1269 bool AccVisitor::NeedsScope(const parser::OpenACCBlockConstruct &x) { 1270 const auto &beginBlockDir{std::get<parser::AccBeginBlockDirective>(x.t)}; 1271 const auto &beginDir{std::get<parser::AccBlockDirective>(beginBlockDir.t)}; 1272 switch (beginDir.v) { 1273 case llvm::acc::Directive::ACCD_data: 1274 case llvm::acc::Directive::ACCD_host_data: 1275 case llvm::acc::Directive::ACCD_kernels: 1276 case llvm::acc::Directive::ACCD_parallel: 1277 case llvm::acc::Directive::ACCD_serial: 1278 return true; 1279 default: 1280 return false; 1281 } 1282 } 1283 1284 void AccVisitor::AddAccSourceRange(const parser::CharBlock &source) { 1285 messageHandler().set_currStmtSource(source); 1286 currScope().AddSourceRange(source); 1287 } 1288 1289 bool AccVisitor::Pre(const parser::OpenACCBlockConstruct &x) { 1290 if (NeedsScope(x)) { 1291 PushScope(Scope::Kind::Block, nullptr); 1292 } 1293 return true; 1294 } 1295 1296 void AccVisitor::Post(const parser::OpenACCBlockConstruct &x) { 1297 if (NeedsScope(x)) { 1298 PopScope(); 1299 } 1300 } 1301 1302 // Create scopes for OpenMP constructs 1303 class OmpVisitor : public virtual DeclarationVisitor { 1304 public: 1305 void AddOmpSourceRange(const parser::CharBlock &); 1306 1307 static bool NeedsScope(const parser::OpenMPBlockConstruct &); 1308 1309 bool Pre(const parser::OpenMPBlockConstruct &); 1310 void Post(const parser::OpenMPBlockConstruct &); 1311 bool Pre(const parser::OmpBeginBlockDirective &x) { 1312 AddOmpSourceRange(x.source); 1313 return true; 1314 } 1315 void Post(const parser::OmpBeginBlockDirective &) { 1316 messageHandler().set_currStmtSource(std::nullopt); 1317 } 1318 bool Pre(const parser::OmpEndBlockDirective &x) { 1319 AddOmpSourceRange(x.source); 1320 return true; 1321 } 1322 void Post(const parser::OmpEndBlockDirective &) { 1323 messageHandler().set_currStmtSource(std::nullopt); 1324 } 1325 1326 bool Pre(const parser::OpenMPLoopConstruct &) { 1327 PushScope(Scope::Kind::Block, nullptr); 1328 return true; 1329 } 1330 void Post(const parser::OpenMPLoopConstruct &) { PopScope(); } 1331 bool Pre(const parser::OmpBeginLoopDirective &x) { 1332 AddOmpSourceRange(x.source); 1333 return true; 1334 } 1335 void Post(const parser::OmpBeginLoopDirective &) { 1336 messageHandler().set_currStmtSource(std::nullopt); 1337 } 1338 bool Pre(const parser::OmpEndLoopDirective &x) { 1339 AddOmpSourceRange(x.source); 1340 return true; 1341 } 1342 void Post(const parser::OmpEndLoopDirective &) { 1343 messageHandler().set_currStmtSource(std::nullopt); 1344 } 1345 1346 bool Pre(const parser::OpenMPSectionsConstruct &) { 1347 PushScope(Scope::Kind::Block, nullptr); 1348 return true; 1349 } 1350 void Post(const parser::OpenMPSectionsConstruct &) { PopScope(); } 1351 bool Pre(const parser::OmpBeginSectionsDirective &x) { 1352 AddOmpSourceRange(x.source); 1353 return true; 1354 } 1355 void Post(const parser::OmpBeginSectionsDirective &) { 1356 messageHandler().set_currStmtSource(std::nullopt); 1357 } 1358 bool Pre(const parser::OmpEndSectionsDirective &x) { 1359 AddOmpSourceRange(x.source); 1360 return true; 1361 } 1362 void Post(const parser::OmpEndSectionsDirective &) { 1363 messageHandler().set_currStmtSource(std::nullopt); 1364 } 1365 }; 1366 1367 bool OmpVisitor::NeedsScope(const parser::OpenMPBlockConstruct &x) { 1368 const auto &beginBlockDir{std::get<parser::OmpBeginBlockDirective>(x.t)}; 1369 const auto &beginDir{std::get<parser::OmpBlockDirective>(beginBlockDir.t)}; 1370 switch (beginDir.v) { 1371 case llvm::omp::Directive::OMPD_target_data: 1372 case llvm::omp::Directive::OMPD_master: 1373 case llvm::omp::Directive::OMPD_ordered: 1374 case llvm::omp::Directive::OMPD_taskgroup: 1375 return false; 1376 default: 1377 return true; 1378 } 1379 } 1380 1381 void OmpVisitor::AddOmpSourceRange(const parser::CharBlock &source) { 1382 messageHandler().set_currStmtSource(source); 1383 currScope().AddSourceRange(source); 1384 } 1385 1386 bool OmpVisitor::Pre(const parser::OpenMPBlockConstruct &x) { 1387 if (NeedsScope(x)) { 1388 PushScope(Scope::Kind::Block, nullptr); 1389 } 1390 return true; 1391 } 1392 1393 void OmpVisitor::Post(const parser::OpenMPBlockConstruct &x) { 1394 if (NeedsScope(x)) { 1395 PopScope(); 1396 } 1397 } 1398 1399 // Walk the parse tree and resolve names to symbols. 1400 class ResolveNamesVisitor : public virtual ScopeHandler, 1401 public ModuleVisitor, 1402 public SubprogramVisitor, 1403 public ConstructVisitor, 1404 public OmpVisitor, 1405 public AccVisitor { 1406 public: 1407 using AccVisitor::Post; 1408 using AccVisitor::Pre; 1409 using ArraySpecVisitor::Post; 1410 using ConstructVisitor::Post; 1411 using ConstructVisitor::Pre; 1412 using DeclarationVisitor::Post; 1413 using DeclarationVisitor::Pre; 1414 using ImplicitRulesVisitor::Post; 1415 using ImplicitRulesVisitor::Pre; 1416 using InterfaceVisitor::Post; 1417 using InterfaceVisitor::Pre; 1418 using ModuleVisitor::Post; 1419 using ModuleVisitor::Pre; 1420 using OmpVisitor::Post; 1421 using OmpVisitor::Pre; 1422 using ScopeHandler::Post; 1423 using ScopeHandler::Pre; 1424 using SubprogramVisitor::Post; 1425 using SubprogramVisitor::Pre; 1426 1427 ResolveNamesVisitor( 1428 SemanticsContext &context, ImplicitRulesMap &rules, Scope &top) 1429 : BaseVisitor{context, *this, rules}, topScope_{top} { 1430 PushScope(top); 1431 } 1432 1433 Scope &topScope() const { return topScope_; } 1434 1435 // Default action for a parse tree node is to visit children. 1436 template <typename T> bool Pre(const T &) { return true; } 1437 template <typename T> void Post(const T &) {} 1438 1439 bool Pre(const parser::SpecificationPart &); 1440 void Post(const parser::Program &); 1441 bool Pre(const parser::ImplicitStmt &); 1442 void Post(const parser::PointerObject &); 1443 void Post(const parser::AllocateObject &); 1444 bool Pre(const parser::PointerAssignmentStmt &); 1445 void Post(const parser::Designator &); 1446 template <typename A, typename B> 1447 void Post(const parser::LoopBounds<A, B> &x) { 1448 ResolveName(*parser::Unwrap<parser::Name>(x.name)); 1449 } 1450 void Post(const parser::ProcComponentRef &); 1451 bool Pre(const parser::FunctionReference &); 1452 bool Pre(const parser::CallStmt &); 1453 bool Pre(const parser::ImportStmt &); 1454 void Post(const parser::TypeGuardStmt &); 1455 bool Pre(const parser::StmtFunctionStmt &); 1456 bool Pre(const parser::DefinedOpName &); 1457 bool Pre(const parser::ProgramUnit &); 1458 void Post(const parser::AssignStmt &); 1459 void Post(const parser::AssignedGotoStmt &); 1460 1461 // These nodes should never be reached: they are handled in ProgramUnit 1462 bool Pre(const parser::MainProgram &) { 1463 llvm_unreachable("This node is handled in ProgramUnit"); 1464 } 1465 bool Pre(const parser::FunctionSubprogram &) { 1466 llvm_unreachable("This node is handled in ProgramUnit"); 1467 } 1468 bool Pre(const parser::SubroutineSubprogram &) { 1469 llvm_unreachable("This node is handled in ProgramUnit"); 1470 } 1471 bool Pre(const parser::SeparateModuleSubprogram &) { 1472 llvm_unreachable("This node is handled in ProgramUnit"); 1473 } 1474 bool Pre(const parser::Module &) { 1475 llvm_unreachable("This node is handled in ProgramUnit"); 1476 } 1477 bool Pre(const parser::Submodule &) { 1478 llvm_unreachable("This node is handled in ProgramUnit"); 1479 } 1480 bool Pre(const parser::BlockData &) { 1481 llvm_unreachable("This node is handled in ProgramUnit"); 1482 } 1483 1484 void NoteExecutablePartCall(Symbol::Flag, const parser::Call &); 1485 1486 friend void ResolveSpecificationParts(SemanticsContext &, const Symbol &); 1487 1488 private: 1489 // Kind of procedure we are expecting to see in a ProcedureDesignator 1490 std::optional<Symbol::Flag> expectedProcFlag_; 1491 std::optional<SourceName> prevImportStmt_; 1492 Scope &topScope_; 1493 1494 void PreSpecificationConstruct(const parser::SpecificationConstruct &); 1495 void CreateCommonBlockSymbols(const parser::CommonStmt &); 1496 void CreateGeneric(const parser::GenericSpec &); 1497 void FinishSpecificationPart(const std::list<parser::DeclarationConstruct> &); 1498 void AnalyzeStmtFunctionStmt(const parser::StmtFunctionStmt &); 1499 void CheckImports(); 1500 void CheckImport(const SourceName &, const SourceName &); 1501 void HandleCall(Symbol::Flag, const parser::Call &); 1502 void HandleProcedureName(Symbol::Flag, const parser::Name &); 1503 bool CheckImplicitNoneExternal(const SourceName &, const Symbol &); 1504 bool SetProcFlag(const parser::Name &, Symbol &, Symbol::Flag); 1505 void ResolveSpecificationParts(ProgramTree &); 1506 void AddSubpNames(ProgramTree &); 1507 bool BeginScopeForNode(const ProgramTree &); 1508 void EndScopeForNode(const ProgramTree &); 1509 void FinishSpecificationParts(const ProgramTree &); 1510 void FinishDerivedTypeInstantiation(Scope &); 1511 void ResolveExecutionParts(const ProgramTree &); 1512 }; 1513 1514 // ImplicitRules implementation 1515 1516 bool ImplicitRules::isImplicitNoneType() const { 1517 if (isImplicitNoneType_) { 1518 return true; 1519 } else if (map_.empty() && inheritFromParent_) { 1520 return parent_->isImplicitNoneType(); 1521 } else { 1522 return false; // default if not specified 1523 } 1524 } 1525 1526 bool ImplicitRules::isImplicitNoneExternal() const { 1527 if (isImplicitNoneExternal_) { 1528 return true; 1529 } else if (inheritFromParent_) { 1530 return parent_->isImplicitNoneExternal(); 1531 } else { 1532 return false; // default if not specified 1533 } 1534 } 1535 1536 const DeclTypeSpec *ImplicitRules::GetType( 1537 SourceName name, bool respectImplicitNoneType) const { 1538 char ch{name.begin()[0]}; 1539 if (isImplicitNoneType_ && respectImplicitNoneType) { 1540 return nullptr; 1541 } else if (auto it{map_.find(ch)}; it != map_.end()) { 1542 return &*it->second; 1543 } else if (inheritFromParent_) { 1544 return parent_->GetType(name, respectImplicitNoneType); 1545 } else if (ch >= 'i' && ch <= 'n') { 1546 return &context_.MakeNumericType(TypeCategory::Integer); 1547 } else if (ch >= 'a' && ch <= 'z') { 1548 return &context_.MakeNumericType(TypeCategory::Real); 1549 } else { 1550 return nullptr; 1551 } 1552 } 1553 1554 void ImplicitRules::SetTypeMapping(const DeclTypeSpec &type, 1555 parser::Location fromLetter, parser::Location toLetter) { 1556 for (char ch = *fromLetter; ch; ch = ImplicitRules::Incr(ch)) { 1557 auto res{map_.emplace(ch, type)}; 1558 if (!res.second) { 1559 context_.Say(parser::CharBlock{fromLetter}, 1560 "More than one implicit type specified for '%c'"_err_en_US, ch); 1561 } 1562 if (ch == *toLetter) { 1563 break; 1564 } 1565 } 1566 } 1567 1568 // Return the next char after ch in a way that works for ASCII or EBCDIC. 1569 // Return '\0' for the char after 'z'. 1570 char ImplicitRules::Incr(char ch) { 1571 switch (ch) { 1572 case 'i': 1573 return 'j'; 1574 case 'r': 1575 return 's'; 1576 case 'z': 1577 return '\0'; 1578 default: 1579 return ch + 1; 1580 } 1581 } 1582 1583 llvm::raw_ostream &operator<<( 1584 llvm::raw_ostream &o, const ImplicitRules &implicitRules) { 1585 o << "ImplicitRules:\n"; 1586 for (char ch = 'a'; ch; ch = ImplicitRules::Incr(ch)) { 1587 ShowImplicitRule(o, implicitRules, ch); 1588 } 1589 ShowImplicitRule(o, implicitRules, '_'); 1590 ShowImplicitRule(o, implicitRules, '$'); 1591 ShowImplicitRule(o, implicitRules, '@'); 1592 return o; 1593 } 1594 void ShowImplicitRule( 1595 llvm::raw_ostream &o, const ImplicitRules &implicitRules, char ch) { 1596 auto it{implicitRules.map_.find(ch)}; 1597 if (it != implicitRules.map_.end()) { 1598 o << " " << ch << ": " << *it->second << '\n'; 1599 } 1600 } 1601 1602 template <typename T> void BaseVisitor::Walk(const T &x) { 1603 parser::Walk(x, *this_); 1604 } 1605 1606 void BaseVisitor::MakePlaceholder( 1607 const parser::Name &name, MiscDetails::Kind kind) { 1608 if (!name.symbol) { 1609 name.symbol = &context_->globalScope().MakeSymbol( 1610 name.source, Attrs{}, MiscDetails{kind}); 1611 } 1612 } 1613 1614 // AttrsVisitor implementation 1615 1616 bool AttrsVisitor::BeginAttrs() { 1617 CHECK(!attrs_); 1618 attrs_ = std::make_optional<Attrs>(); 1619 return true; 1620 } 1621 Attrs AttrsVisitor::GetAttrs() { 1622 CHECK(attrs_); 1623 return *attrs_; 1624 } 1625 Attrs AttrsVisitor::EndAttrs() { 1626 Attrs result{GetAttrs()}; 1627 attrs_.reset(); 1628 passName_ = std::nullopt; 1629 bindName_.reset(); 1630 return result; 1631 } 1632 1633 bool AttrsVisitor::SetPassNameOn(Symbol &symbol) { 1634 if (!passName_) { 1635 return false; 1636 } 1637 common::visit(common::visitors{ 1638 [&](ProcEntityDetails &x) { x.set_passName(*passName_); }, 1639 [&](ProcBindingDetails &x) { x.set_passName(*passName_); }, 1640 [](auto &) { common::die("unexpected pass name"); }, 1641 }, 1642 symbol.details()); 1643 return true; 1644 } 1645 1646 void AttrsVisitor::SetBindNameOn(Symbol &symbol) { 1647 if (!attrs_ || !attrs_->test(Attr::BIND_C)) { 1648 return; 1649 } 1650 std::optional<std::string> label{ 1651 evaluate::GetScalarConstantValue<evaluate::Ascii>(bindName_)}; 1652 // 18.9.2(2): discard leading and trailing blanks, ignore if all blank 1653 if (label) { 1654 auto first{label->find_first_not_of(" ")}; 1655 if (first == std::string::npos) { 1656 // Empty NAME= means no binding at all (18.10.2p2) 1657 Say(currStmtSource().value(), "Blank binding label ignored"_warn_en_US); 1658 return; 1659 } 1660 auto last{label->find_last_not_of(" ")}; 1661 label = label->substr(first, last - first + 1); 1662 } else { 1663 label = parser::ToLowerCaseLetters(symbol.name().ToString()); 1664 } 1665 symbol.SetBindName(std::move(*label)); 1666 } 1667 1668 void AttrsVisitor::Post(const parser::LanguageBindingSpec &x) { 1669 CHECK(attrs_); 1670 if (CheckAndSet(Attr::BIND_C)) { 1671 if (x.v) { 1672 bindName_ = EvaluateExpr(*x.v); 1673 } 1674 } 1675 } 1676 bool AttrsVisitor::Pre(const parser::IntentSpec &x) { 1677 CHECK(attrs_); 1678 CheckAndSet(IntentSpecToAttr(x)); 1679 return false; 1680 } 1681 bool AttrsVisitor::Pre(const parser::Pass &x) { 1682 if (CheckAndSet(Attr::PASS)) { 1683 if (x.v) { 1684 passName_ = x.v->source; 1685 MakePlaceholder(*x.v, MiscDetails::Kind::PassName); 1686 } 1687 } 1688 return false; 1689 } 1690 1691 // C730, C743, C755, C778, C1543 say no attribute or prefix repetitions 1692 bool AttrsVisitor::IsDuplicateAttr(Attr attrName) { 1693 if (attrs_->test(attrName)) { 1694 Say(currStmtSource().value(), 1695 "Attribute '%s' cannot be used more than once"_warn_en_US, 1696 AttrToString(attrName)); 1697 return true; 1698 } 1699 return false; 1700 } 1701 1702 // See if attrName violates a constraint cause by a conflict. attr1 and attr2 1703 // name attributes that cannot be used on the same declaration 1704 bool AttrsVisitor::HaveAttrConflict(Attr attrName, Attr attr1, Attr attr2) { 1705 if ((attrName == attr1 && attrs_->test(attr2)) || 1706 (attrName == attr2 && attrs_->test(attr1))) { 1707 Say(currStmtSource().value(), 1708 "Attributes '%s' and '%s' conflict with each other"_err_en_US, 1709 AttrToString(attr1), AttrToString(attr2)); 1710 return true; 1711 } 1712 return false; 1713 } 1714 // C759, C1543 1715 bool AttrsVisitor::IsConflictingAttr(Attr attrName) { 1716 return HaveAttrConflict(attrName, Attr::INTENT_IN, Attr::INTENT_INOUT) || 1717 HaveAttrConflict(attrName, Attr::INTENT_IN, Attr::INTENT_OUT) || 1718 HaveAttrConflict(attrName, Attr::INTENT_INOUT, Attr::INTENT_OUT) || 1719 HaveAttrConflict(attrName, Attr::PASS, Attr::NOPASS) || // C781 1720 HaveAttrConflict(attrName, Attr::PURE, Attr::IMPURE) || 1721 HaveAttrConflict(attrName, Attr::PUBLIC, Attr::PRIVATE) || 1722 HaveAttrConflict(attrName, Attr::RECURSIVE, Attr::NON_RECURSIVE); 1723 } 1724 bool AttrsVisitor::CheckAndSet(Attr attrName) { 1725 CHECK(attrs_); 1726 if (IsConflictingAttr(attrName) || IsDuplicateAttr(attrName)) { 1727 return false; 1728 } 1729 attrs_->set(attrName); 1730 return true; 1731 } 1732 1733 // DeclTypeSpecVisitor implementation 1734 1735 const DeclTypeSpec *DeclTypeSpecVisitor::GetDeclTypeSpec() { 1736 return state_.declTypeSpec; 1737 } 1738 1739 void DeclTypeSpecVisitor::BeginDeclTypeSpec() { 1740 CHECK(!state_.expectDeclTypeSpec); 1741 CHECK(!state_.declTypeSpec); 1742 state_.expectDeclTypeSpec = true; 1743 } 1744 void DeclTypeSpecVisitor::EndDeclTypeSpec() { 1745 CHECK(state_.expectDeclTypeSpec); 1746 state_ = {}; 1747 } 1748 1749 void DeclTypeSpecVisitor::SetDeclTypeSpecCategory( 1750 DeclTypeSpec::Category category) { 1751 CHECK(state_.expectDeclTypeSpec); 1752 state_.derived.category = category; 1753 } 1754 1755 bool DeclTypeSpecVisitor::Pre(const parser::TypeGuardStmt &) { 1756 BeginDeclTypeSpec(); 1757 return true; 1758 } 1759 void DeclTypeSpecVisitor::Post(const parser::TypeGuardStmt &) { 1760 EndDeclTypeSpec(); 1761 } 1762 1763 void DeclTypeSpecVisitor::Post(const parser::TypeSpec &typeSpec) { 1764 // Record the resolved DeclTypeSpec in the parse tree for use by 1765 // expression semantics if the DeclTypeSpec is a valid TypeSpec. 1766 // The grammar ensures that it's an intrinsic or derived type spec, 1767 // not TYPE(*) or CLASS(*) or CLASS(T). 1768 if (const DeclTypeSpec * spec{state_.declTypeSpec}) { 1769 switch (spec->category()) { 1770 case DeclTypeSpec::Numeric: 1771 case DeclTypeSpec::Logical: 1772 case DeclTypeSpec::Character: 1773 typeSpec.declTypeSpec = spec; 1774 break; 1775 case DeclTypeSpec::TypeDerived: 1776 if (const DerivedTypeSpec * derived{spec->AsDerived()}) { 1777 CheckForAbstractType(derived->typeSymbol()); // C703 1778 typeSpec.declTypeSpec = spec; 1779 } 1780 break; 1781 default: 1782 CRASH_NO_CASE; 1783 } 1784 } 1785 } 1786 1787 void DeclTypeSpecVisitor::Post( 1788 const parser::IntrinsicTypeSpec::DoublePrecision &) { 1789 MakeNumericType(TypeCategory::Real, context().doublePrecisionKind()); 1790 } 1791 void DeclTypeSpecVisitor::Post( 1792 const parser::IntrinsicTypeSpec::DoubleComplex &) { 1793 MakeNumericType(TypeCategory::Complex, context().doublePrecisionKind()); 1794 } 1795 void DeclTypeSpecVisitor::MakeNumericType(TypeCategory category, int kind) { 1796 SetDeclTypeSpec(context().MakeNumericType(category, kind)); 1797 } 1798 1799 void DeclTypeSpecVisitor::CheckForAbstractType(const Symbol &typeSymbol) { 1800 if (typeSymbol.attrs().test(Attr::ABSTRACT)) { 1801 Say("ABSTRACT derived type may not be used here"_err_en_US); 1802 } 1803 } 1804 1805 void DeclTypeSpecVisitor::Post(const parser::DeclarationTypeSpec::ClassStar &) { 1806 SetDeclTypeSpec(context().globalScope().MakeClassStarType()); 1807 } 1808 void DeclTypeSpecVisitor::Post(const parser::DeclarationTypeSpec::TypeStar &) { 1809 SetDeclTypeSpec(context().globalScope().MakeTypeStarType()); 1810 } 1811 1812 // Check that we're expecting to see a DeclTypeSpec (and haven't seen one yet) 1813 // and save it in state_.declTypeSpec. 1814 void DeclTypeSpecVisitor::SetDeclTypeSpec(const DeclTypeSpec &declTypeSpec) { 1815 CHECK(state_.expectDeclTypeSpec); 1816 CHECK(!state_.declTypeSpec); 1817 state_.declTypeSpec = &declTypeSpec; 1818 } 1819 1820 KindExpr DeclTypeSpecVisitor::GetKindParamExpr( 1821 TypeCategory category, const std::optional<parser::KindSelector> &kind) { 1822 return AnalyzeKindSelector(context(), category, kind); 1823 } 1824 1825 // MessageHandler implementation 1826 1827 Message &MessageHandler::Say(MessageFixedText &&msg) { 1828 return context_->Say(currStmtSource().value(), std::move(msg)); 1829 } 1830 Message &MessageHandler::Say(MessageFormattedText &&msg) { 1831 return context_->Say(currStmtSource().value(), std::move(msg)); 1832 } 1833 Message &MessageHandler::Say(const SourceName &name, MessageFixedText &&msg) { 1834 return Say(name, std::move(msg), name); 1835 } 1836 1837 // ImplicitRulesVisitor implementation 1838 1839 void ImplicitRulesVisitor::Post(const parser::ParameterStmt &) { 1840 prevParameterStmt_ = currStmtSource(); 1841 } 1842 1843 bool ImplicitRulesVisitor::Pre(const parser::ImplicitStmt &x) { 1844 bool result{ 1845 common::visit(common::visitors{ 1846 [&](const std::list<ImplicitNoneNameSpec> &y) { 1847 return HandleImplicitNone(y); 1848 }, 1849 [&](const std::list<parser::ImplicitSpec> &) { 1850 if (prevImplicitNoneType_) { 1851 Say("IMPLICIT statement after IMPLICIT NONE or " 1852 "IMPLICIT NONE(TYPE) statement"_err_en_US); 1853 return false; 1854 } 1855 implicitRules_->set_isImplicitNoneType(false); 1856 return true; 1857 }, 1858 }, 1859 x.u)}; 1860 prevImplicit_ = currStmtSource(); 1861 return result; 1862 } 1863 1864 bool ImplicitRulesVisitor::Pre(const parser::LetterSpec &x) { 1865 auto loLoc{std::get<parser::Location>(x.t)}; 1866 auto hiLoc{loLoc}; 1867 if (auto hiLocOpt{std::get<std::optional<parser::Location>>(x.t)}) { 1868 hiLoc = *hiLocOpt; 1869 if (*hiLoc < *loLoc) { 1870 Say(hiLoc, "'%s' does not follow '%s' alphabetically"_err_en_US, 1871 std::string(hiLoc, 1), std::string(loLoc, 1)); 1872 return false; 1873 } 1874 } 1875 implicitRules_->SetTypeMapping(*GetDeclTypeSpec(), loLoc, hiLoc); 1876 return false; 1877 } 1878 1879 bool ImplicitRulesVisitor::Pre(const parser::ImplicitSpec &) { 1880 BeginDeclTypeSpec(); 1881 set_allowForwardReferenceToDerivedType(true); 1882 return true; 1883 } 1884 1885 void ImplicitRulesVisitor::Post(const parser::ImplicitSpec &) { 1886 EndDeclTypeSpec(); 1887 } 1888 1889 void ImplicitRulesVisitor::SetScope(const Scope &scope) { 1890 implicitRules_ = &DEREF(implicitRulesMap_).at(&scope); 1891 prevImplicit_ = std::nullopt; 1892 prevImplicitNone_ = std::nullopt; 1893 prevImplicitNoneType_ = std::nullopt; 1894 prevParameterStmt_ = std::nullopt; 1895 } 1896 void ImplicitRulesVisitor::BeginScope(const Scope &scope) { 1897 // find or create implicit rules for this scope 1898 DEREF(implicitRulesMap_).try_emplace(&scope, context(), implicitRules_); 1899 SetScope(scope); 1900 } 1901 1902 // TODO: for all of these errors, reference previous statement too 1903 bool ImplicitRulesVisitor::HandleImplicitNone( 1904 const std::list<ImplicitNoneNameSpec> &nameSpecs) { 1905 if (prevImplicitNone_) { 1906 Say("More than one IMPLICIT NONE statement"_err_en_US); 1907 Say(*prevImplicitNone_, "Previous IMPLICIT NONE statement"_en_US); 1908 return false; 1909 } 1910 if (prevParameterStmt_) { 1911 Say("IMPLICIT NONE statement after PARAMETER statement"_err_en_US); 1912 return false; 1913 } 1914 prevImplicitNone_ = currStmtSource(); 1915 bool implicitNoneTypeNever{ 1916 context().IsEnabled(common::LanguageFeature::ImplicitNoneTypeNever)}; 1917 if (nameSpecs.empty()) { 1918 if (!implicitNoneTypeNever) { 1919 prevImplicitNoneType_ = currStmtSource(); 1920 implicitRules_->set_isImplicitNoneType(true); 1921 if (prevImplicit_) { 1922 Say("IMPLICIT NONE statement after IMPLICIT statement"_err_en_US); 1923 return false; 1924 } 1925 } 1926 } else { 1927 int sawType{0}; 1928 int sawExternal{0}; 1929 for (const auto noneSpec : nameSpecs) { 1930 switch (noneSpec) { 1931 case ImplicitNoneNameSpec::External: 1932 implicitRules_->set_isImplicitNoneExternal(true); 1933 ++sawExternal; 1934 break; 1935 case ImplicitNoneNameSpec::Type: 1936 if (!implicitNoneTypeNever) { 1937 prevImplicitNoneType_ = currStmtSource(); 1938 implicitRules_->set_isImplicitNoneType(true); 1939 if (prevImplicit_) { 1940 Say("IMPLICIT NONE(TYPE) after IMPLICIT statement"_err_en_US); 1941 return false; 1942 } 1943 ++sawType; 1944 } 1945 break; 1946 } 1947 } 1948 if (sawType > 1) { 1949 Say("TYPE specified more than once in IMPLICIT NONE statement"_err_en_US); 1950 return false; 1951 } 1952 if (sawExternal > 1) { 1953 Say("EXTERNAL specified more than once in IMPLICIT NONE statement"_err_en_US); 1954 return false; 1955 } 1956 } 1957 return true; 1958 } 1959 1960 // ArraySpecVisitor implementation 1961 1962 void ArraySpecVisitor::Post(const parser::ArraySpec &x) { 1963 CHECK(arraySpec_.empty()); 1964 arraySpec_ = AnalyzeArraySpec(context(), x); 1965 } 1966 void ArraySpecVisitor::Post(const parser::ComponentArraySpec &x) { 1967 CHECK(arraySpec_.empty()); 1968 arraySpec_ = AnalyzeArraySpec(context(), x); 1969 } 1970 void ArraySpecVisitor::Post(const parser::CoarraySpec &x) { 1971 CHECK(coarraySpec_.empty()); 1972 coarraySpec_ = AnalyzeCoarraySpec(context(), x); 1973 } 1974 1975 const ArraySpec &ArraySpecVisitor::arraySpec() { 1976 return !arraySpec_.empty() ? arraySpec_ : attrArraySpec_; 1977 } 1978 const ArraySpec &ArraySpecVisitor::coarraySpec() { 1979 return !coarraySpec_.empty() ? coarraySpec_ : attrCoarraySpec_; 1980 } 1981 void ArraySpecVisitor::BeginArraySpec() { 1982 CHECK(arraySpec_.empty()); 1983 CHECK(coarraySpec_.empty()); 1984 CHECK(attrArraySpec_.empty()); 1985 CHECK(attrCoarraySpec_.empty()); 1986 } 1987 void ArraySpecVisitor::EndArraySpec() { 1988 CHECK(arraySpec_.empty()); 1989 CHECK(coarraySpec_.empty()); 1990 attrArraySpec_.clear(); 1991 attrCoarraySpec_.clear(); 1992 } 1993 void ArraySpecVisitor::PostAttrSpec() { 1994 // Save dimension/codimension from attrs so we can process array/coarray-spec 1995 // on the entity-decl 1996 if (!arraySpec_.empty()) { 1997 if (attrArraySpec_.empty()) { 1998 attrArraySpec_ = arraySpec_; 1999 arraySpec_.clear(); 2000 } else { 2001 Say(currStmtSource().value(), 2002 "Attribute 'DIMENSION' cannot be used more than once"_err_en_US); 2003 } 2004 } 2005 if (!coarraySpec_.empty()) { 2006 if (attrCoarraySpec_.empty()) { 2007 attrCoarraySpec_ = coarraySpec_; 2008 coarraySpec_.clear(); 2009 } else { 2010 Say(currStmtSource().value(), 2011 "Attribute 'CODIMENSION' cannot be used more than once"_err_en_US); 2012 } 2013 } 2014 } 2015 2016 // FuncResultStack implementation 2017 2018 FuncResultStack::~FuncResultStack() { CHECK(stack_.empty()); } 2019 2020 void FuncResultStack::CompleteFunctionResultType() { 2021 // If the function has a type in the prefix, process it now. 2022 if (IsFunction(scopeHandler_.currScope())) { 2023 FuncInfo &info{DEREF(Top())}; 2024 if (info.parsedType) { 2025 scopeHandler_.messageHandler().set_currStmtSource(info.source); 2026 if (const auto *type{ 2027 scopeHandler_.ProcessTypeSpec(*info.parsedType, true)}) { 2028 if (!scopeHandler_.context().HasError(info.resultSymbol)) { 2029 info.resultSymbol->SetType(*type); 2030 } 2031 } 2032 info.parsedType = nullptr; 2033 } 2034 } 2035 } 2036 2037 // Called from ConvertTo{Object/Proc}Entity to cope with any appearance 2038 // of the function result in a specification expression. 2039 void FuncResultStack::CompleteTypeIfFunctionResult(Symbol &symbol) { 2040 if (FuncInfo * info{Top()}) { 2041 if (info->resultSymbol == &symbol) { 2042 CompleteFunctionResultType(); 2043 } 2044 } 2045 } 2046 2047 // ScopeHandler implementation 2048 2049 void ScopeHandler::SayAlreadyDeclared(const parser::Name &name, Symbol &prev) { 2050 SayAlreadyDeclared(name.source, prev); 2051 } 2052 void ScopeHandler::SayAlreadyDeclared(const SourceName &name, Symbol &prev) { 2053 if (context().HasError(prev)) { 2054 // don't report another error about prev 2055 } else { 2056 if (const auto *details{prev.detailsIf<UseDetails>()}) { 2057 Say(name, "'%s' is already declared in this scoping unit"_err_en_US) 2058 .Attach(details->location(), 2059 "It is use-associated with '%s' in module '%s'"_en_US, 2060 details->symbol().name(), GetUsedModule(*details).name()); 2061 } else { 2062 SayAlreadyDeclared(name, prev.name()); 2063 } 2064 context().SetError(prev); 2065 } 2066 } 2067 void ScopeHandler::SayAlreadyDeclared( 2068 const SourceName &name1, const SourceName &name2) { 2069 if (name1.begin() < name2.begin()) { 2070 SayAlreadyDeclared(name2, name1); 2071 } else { 2072 Say(name1, "'%s' is already declared in this scoping unit"_err_en_US) 2073 .Attach(name2, "Previous declaration of '%s'"_en_US, name2); 2074 } 2075 } 2076 2077 void ScopeHandler::SayWithReason(const parser::Name &name, Symbol &symbol, 2078 MessageFixedText &&msg1, Message &&msg2) { 2079 Say(name, std::move(msg1), symbol.name()).Attach(std::move(msg2)); 2080 context().SetError(symbol, msg1.isFatal()); 2081 } 2082 2083 void ScopeHandler::SayWithDecl( 2084 const parser::Name &name, Symbol &symbol, MessageFixedText &&msg) { 2085 Say(name, std::move(msg), symbol.name()) 2086 .Attach(Message{name.source, 2087 symbol.test(Symbol::Flag::Implicit) 2088 ? "Implicit declaration of '%s'"_en_US 2089 : "Declaration of '%s'"_en_US, 2090 name.source}); 2091 context().SetError(symbol, msg.isFatal()); 2092 } 2093 2094 void ScopeHandler::SayLocalMustBeVariable( 2095 const parser::Name &name, Symbol &symbol) { 2096 SayWithDecl(name, symbol, 2097 "The name '%s' must be a variable to appear" 2098 " in a locality-spec"_err_en_US); 2099 } 2100 2101 void ScopeHandler::SayDerivedType( 2102 const SourceName &name, MessageFixedText &&msg, const Scope &type) { 2103 const Symbol &typeSymbol{DEREF(type.GetSymbol())}; 2104 Say(name, std::move(msg), name, typeSymbol.name()) 2105 .Attach(typeSymbol.name(), "Declaration of derived type '%s'"_en_US, 2106 typeSymbol.name()); 2107 } 2108 void ScopeHandler::Say2(const SourceName &name1, MessageFixedText &&msg1, 2109 const SourceName &name2, MessageFixedText &&msg2) { 2110 Say(name1, std::move(msg1)).Attach(name2, std::move(msg2), name2); 2111 } 2112 void ScopeHandler::Say2(const SourceName &name, MessageFixedText &&msg1, 2113 Symbol &symbol, MessageFixedText &&msg2) { 2114 Say2(name, std::move(msg1), symbol.name(), std::move(msg2)); 2115 context().SetError(symbol, msg1.isFatal()); 2116 } 2117 void ScopeHandler::Say2(const parser::Name &name, MessageFixedText &&msg1, 2118 Symbol &symbol, MessageFixedText &&msg2) { 2119 Say2(name.source, std::move(msg1), symbol.name(), std::move(msg2)); 2120 context().SetError(symbol, msg1.isFatal()); 2121 } 2122 2123 // This is essentially GetProgramUnitContaining(), but it can return 2124 // a mutable Scope &, it ignores statement functions, and it fails 2125 // gracefully for error recovery (returning the original Scope). 2126 template <typename T> static T &GetInclusiveScope(T &scope) { 2127 for (T *s{&scope}; !s->IsGlobal(); s = &s->parent()) { 2128 switch (s->kind()) { 2129 case Scope::Kind::Module: 2130 case Scope::Kind::MainProgram: 2131 case Scope::Kind::Subprogram: 2132 case Scope::Kind::BlockData: 2133 if (!s->IsStmtFunction()) { 2134 return *s; 2135 } 2136 break; 2137 default:; 2138 } 2139 } 2140 return scope; 2141 } 2142 2143 Scope &ScopeHandler::InclusiveScope() { return GetInclusiveScope(currScope()); } 2144 2145 Scope *ScopeHandler::GetHostProcedure() { 2146 Scope &parent{InclusiveScope().parent()}; 2147 switch (parent.kind()) { 2148 case Scope::Kind::Subprogram: 2149 return &parent; 2150 case Scope::Kind::MainProgram: 2151 return &parent; 2152 default: 2153 return nullptr; 2154 } 2155 } 2156 2157 Scope &ScopeHandler::NonDerivedTypeScope() { 2158 return currScope_->IsDerivedType() ? currScope_->parent() : *currScope_; 2159 } 2160 2161 void ScopeHandler::PushScope(Scope::Kind kind, Symbol *symbol) { 2162 PushScope(currScope().MakeScope(kind, symbol)); 2163 } 2164 void ScopeHandler::PushScope(Scope &scope) { 2165 currScope_ = &scope; 2166 auto kind{currScope_->kind()}; 2167 if (kind != Scope::Kind::Block) { 2168 BeginScope(scope); 2169 } 2170 // The name of a module or submodule cannot be "used" in its scope, 2171 // as we read 19.3.1(2), so we allow the name to be used as a local 2172 // identifier in the module or submodule too. Same with programs 2173 // (14.1(3)) and BLOCK DATA. 2174 if (!currScope_->IsDerivedType() && kind != Scope::Kind::Module && 2175 kind != Scope::Kind::MainProgram && kind != Scope::Kind::BlockData) { 2176 if (auto *symbol{scope.symbol()}) { 2177 // Create a dummy symbol so we can't create another one with the same 2178 // name. It might already be there if we previously pushed the scope. 2179 if (!FindInScope(scope, symbol->name())) { 2180 auto &newSymbol{MakeSymbol(symbol->name())}; 2181 if (kind == Scope::Kind::Subprogram) { 2182 // Allow for recursive references. If this symbol is a function 2183 // without an explicit RESULT(), this new symbol will be discarded 2184 // and replaced with an object of the same name. 2185 newSymbol.set_details(HostAssocDetails{*symbol}); 2186 } else { 2187 newSymbol.set_details(MiscDetails{MiscDetails::Kind::ScopeName}); 2188 } 2189 } 2190 } 2191 } 2192 } 2193 void ScopeHandler::PopScope() { 2194 // Entities that are not yet classified as objects or procedures are now 2195 // assumed to be objects. 2196 // TODO: Statement functions 2197 for (auto &pair : currScope()) { 2198 ConvertToObjectEntity(*pair.second); 2199 } 2200 SetScope(currScope_->parent()); 2201 } 2202 void ScopeHandler::SetScope(Scope &scope) { 2203 currScope_ = &scope; 2204 ImplicitRulesVisitor::SetScope(InclusiveScope()); 2205 } 2206 2207 Symbol *ScopeHandler::FindSymbol(const parser::Name &name) { 2208 return FindSymbol(currScope(), name); 2209 } 2210 Symbol *ScopeHandler::FindSymbol(const Scope &scope, const parser::Name &name) { 2211 if (scope.IsDerivedType()) { 2212 if (Symbol * symbol{scope.FindComponent(name.source)}) { 2213 if (!symbol->has<ProcBindingDetails>() && 2214 !symbol->test(Symbol::Flag::ParentComp)) { 2215 return Resolve(name, symbol); 2216 } 2217 } 2218 return FindSymbol(scope.parent(), name); 2219 } else { 2220 // In EQUIVALENCE statements only resolve names in the local scope, see 2221 // 19.5.1.4, paragraph 2, item (10) 2222 return Resolve(name, 2223 inEquivalenceStmt_ ? FindInScope(scope, name) 2224 : scope.FindSymbol(name.source)); 2225 } 2226 } 2227 2228 Symbol &ScopeHandler::MakeSymbol( 2229 Scope &scope, const SourceName &name, Attrs attrs) { 2230 if (Symbol * symbol{FindInScope(scope, name)}) { 2231 symbol->attrs() |= attrs; 2232 return *symbol; 2233 } else { 2234 const auto pair{scope.try_emplace(name, attrs, UnknownDetails{})}; 2235 CHECK(pair.second); // name was not found, so must be able to add 2236 return *pair.first->second; 2237 } 2238 } 2239 Symbol &ScopeHandler::MakeSymbol(const SourceName &name, Attrs attrs) { 2240 return MakeSymbol(currScope(), name, attrs); 2241 } 2242 Symbol &ScopeHandler::MakeSymbol(const parser::Name &name, Attrs attrs) { 2243 return Resolve(name, MakeSymbol(name.source, attrs)); 2244 } 2245 Symbol &ScopeHandler::MakeHostAssocSymbol( 2246 const parser::Name &name, const Symbol &hostSymbol) { 2247 Symbol &symbol{*NonDerivedTypeScope() 2248 .try_emplace(name.source, HostAssocDetails{hostSymbol}) 2249 .first->second}; 2250 name.symbol = &symbol; 2251 symbol.attrs() = hostSymbol.attrs(); // TODO: except PRIVATE, PUBLIC? 2252 symbol.flags() = hostSymbol.flags(); 2253 return symbol; 2254 } 2255 Symbol &ScopeHandler::CopySymbol(const SourceName &name, const Symbol &symbol) { 2256 CHECK(!FindInScope(name)); 2257 return MakeSymbol(currScope(), name, symbol.attrs()); 2258 } 2259 2260 // Look for name only in scope, not in enclosing scopes. 2261 Symbol *ScopeHandler::FindInScope( 2262 const Scope &scope, const parser::Name &name) { 2263 return Resolve(name, FindInScope(scope, name.source)); 2264 } 2265 Symbol *ScopeHandler::FindInScope(const Scope &scope, const SourceName &name) { 2266 // all variants of names, e.g. "operator(.ne.)" for "operator(/=)" 2267 for (const std::string &n : GetAllNames(context(), name)) { 2268 auto it{scope.find(SourceName{n})}; 2269 if (it != scope.end()) { 2270 return &*it->second; 2271 } 2272 } 2273 return nullptr; 2274 } 2275 2276 // Find a component or type parameter by name in a derived type or its parents. 2277 Symbol *ScopeHandler::FindInTypeOrParents( 2278 const Scope &scope, const parser::Name &name) { 2279 return Resolve(name, scope.FindComponent(name.source)); 2280 } 2281 Symbol *ScopeHandler::FindInTypeOrParents(const parser::Name &name) { 2282 return FindInTypeOrParents(currScope(), name); 2283 } 2284 2285 void ScopeHandler::EraseSymbol(const parser::Name &name) { 2286 currScope().erase(name.source); 2287 name.symbol = nullptr; 2288 } 2289 2290 static bool NeedsType(const Symbol &symbol) { 2291 return !symbol.GetType() && 2292 common::visit(common::visitors{ 2293 [](const EntityDetails &) { return true; }, 2294 [](const ObjectEntityDetails &) { return true; }, 2295 [](const AssocEntityDetails &) { return true; }, 2296 [&](const ProcEntityDetails &p) { 2297 return symbol.test(Symbol::Flag::Function) && 2298 !symbol.attrs().test(Attr::INTRINSIC) && 2299 !p.interface().type() && !p.interface().symbol(); 2300 }, 2301 [](const auto &) { return false; }, 2302 }, 2303 symbol.details()); 2304 } 2305 2306 void ScopeHandler::ApplyImplicitRules( 2307 Symbol &symbol, bool allowForwardReference) { 2308 funcResultStack_.CompleteTypeIfFunctionResult(symbol); 2309 if (context().HasError(symbol) || !NeedsType(symbol)) { 2310 return; 2311 } 2312 if (const DeclTypeSpec * type{GetImplicitType(symbol)}) { 2313 symbol.set(Symbol::Flag::Implicit); 2314 symbol.SetType(*type); 2315 return; 2316 } 2317 if (symbol.has<ProcEntityDetails>() && !symbol.attrs().test(Attr::EXTERNAL)) { 2318 std::optional<Symbol::Flag> functionOrSubroutineFlag; 2319 if (symbol.test(Symbol::Flag::Function)) { 2320 functionOrSubroutineFlag = Symbol::Flag::Function; 2321 } else if (symbol.test(Symbol::Flag::Subroutine)) { 2322 functionOrSubroutineFlag = Symbol::Flag::Subroutine; 2323 } 2324 if (IsIntrinsic(symbol.name(), functionOrSubroutineFlag)) { 2325 // type will be determined in expression semantics 2326 AcquireIntrinsicProcedureFlags(symbol); 2327 return; 2328 } 2329 } 2330 if (allowForwardReference && ImplicitlyTypeForwardRef(symbol)) { 2331 return; 2332 } 2333 if (!context().HasError(symbol)) { 2334 Say(symbol.name(), "No explicit type declared for '%s'"_err_en_US); 2335 context().SetError(symbol); 2336 } 2337 } 2338 2339 // Extension: Allow forward references to scalar integer dummy arguments 2340 // to appear in specification expressions under IMPLICIT NONE(TYPE) when 2341 // what would otherwise have been their implicit type is default INTEGER. 2342 bool ScopeHandler::ImplicitlyTypeForwardRef(Symbol &symbol) { 2343 if (!inSpecificationPart_ || context().HasError(symbol) || !IsDummy(symbol) || 2344 symbol.Rank() != 0 || 2345 !context().languageFeatures().IsEnabled( 2346 common::LanguageFeature::ForwardRefDummyImplicitNone)) { 2347 return false; 2348 } 2349 const DeclTypeSpec *type{ 2350 GetImplicitType(symbol, false /*ignore IMPLICIT NONE*/)}; 2351 if (!type || !type->IsNumeric(TypeCategory::Integer)) { 2352 return false; 2353 } 2354 auto kind{evaluate::ToInt64(type->numericTypeSpec().kind())}; 2355 if (!kind || *kind != context().GetDefaultKind(TypeCategory::Integer)) { 2356 return false; 2357 } 2358 if (!ConvertToObjectEntity(symbol)) { 2359 return false; 2360 } 2361 // TODO: check no INTENT(OUT)? 2362 if (context().languageFeatures().ShouldWarn( 2363 common::LanguageFeature::ForwardRefDummyImplicitNone)) { 2364 Say(symbol.name(), 2365 "Dummy argument '%s' was used without being explicitly typed"_warn_en_US, 2366 symbol.name()); 2367 } 2368 symbol.set(Symbol::Flag::Implicit); 2369 symbol.SetType(*type); 2370 return true; 2371 } 2372 2373 // Ensure that the symbol for an intrinsic procedure is marked with 2374 // the INTRINSIC attribute. Also set PURE &/or ELEMENTAL as 2375 // appropriate. 2376 void ScopeHandler::AcquireIntrinsicProcedureFlags(Symbol &symbol) { 2377 symbol.attrs().set(Attr::INTRINSIC); 2378 switch (context().intrinsics().GetIntrinsicClass(symbol.name().ToString())) { 2379 case evaluate::IntrinsicClass::elementalFunction: 2380 case evaluate::IntrinsicClass::elementalSubroutine: 2381 symbol.attrs().set(Attr::ELEMENTAL); 2382 symbol.attrs().set(Attr::PURE); 2383 break; 2384 case evaluate::IntrinsicClass::impureSubroutine: 2385 break; 2386 default: 2387 symbol.attrs().set(Attr::PURE); 2388 } 2389 } 2390 2391 const DeclTypeSpec *ScopeHandler::GetImplicitType( 2392 Symbol &symbol, bool respectImplicitNoneType) { 2393 const Scope *scope{&symbol.owner()}; 2394 if (scope->IsGlobal()) { 2395 scope = &currScope(); 2396 } 2397 scope = &GetInclusiveScope(*scope); 2398 const auto *type{implicitRulesMap_->at(scope).GetType( 2399 symbol.name(), respectImplicitNoneType)}; 2400 if (type) { 2401 if (const DerivedTypeSpec * derived{type->AsDerived()}) { 2402 // Resolve any forward-referenced derived type; a quick no-op else. 2403 auto &instantiatable{*const_cast<DerivedTypeSpec *>(derived)}; 2404 instantiatable.Instantiate(currScope()); 2405 } 2406 } 2407 return type; 2408 } 2409 2410 // Convert symbol to be a ObjectEntity or return false if it can't be. 2411 bool ScopeHandler::ConvertToObjectEntity(Symbol &symbol) { 2412 if (symbol.has<ObjectEntityDetails>()) { 2413 // nothing to do 2414 } else if (symbol.has<UnknownDetails>()) { 2415 symbol.set_details(ObjectEntityDetails{}); 2416 } else if (auto *details{symbol.detailsIf<EntityDetails>()}) { 2417 funcResultStack_.CompleteTypeIfFunctionResult(symbol); 2418 symbol.set_details(ObjectEntityDetails{std::move(*details)}); 2419 } else if (auto *useDetails{symbol.detailsIf<UseDetails>()}) { 2420 return useDetails->symbol().has<ObjectEntityDetails>(); 2421 } else { 2422 return false; 2423 } 2424 return true; 2425 } 2426 // Convert symbol to be a ProcEntity or return false if it can't be. 2427 bool ScopeHandler::ConvertToProcEntity(Symbol &symbol) { 2428 if (symbol.has<ProcEntityDetails>()) { 2429 // nothing to do 2430 } else if (symbol.has<UnknownDetails>()) { 2431 symbol.set_details(ProcEntityDetails{}); 2432 } else if (auto *details{symbol.detailsIf<EntityDetails>()}) { 2433 funcResultStack_.CompleteTypeIfFunctionResult(symbol); 2434 symbol.set_details(ProcEntityDetails{std::move(*details)}); 2435 if (symbol.GetType() && !symbol.test(Symbol::Flag::Implicit)) { 2436 CHECK(!symbol.test(Symbol::Flag::Subroutine)); 2437 symbol.set(Symbol::Flag::Function); 2438 } 2439 } else { 2440 return false; 2441 } 2442 return true; 2443 } 2444 2445 const DeclTypeSpec &ScopeHandler::MakeNumericType( 2446 TypeCategory category, const std::optional<parser::KindSelector> &kind) { 2447 KindExpr value{GetKindParamExpr(category, kind)}; 2448 if (auto known{evaluate::ToInt64(value)}) { 2449 return context().MakeNumericType(category, static_cast<int>(*known)); 2450 } else { 2451 return currScope_->MakeNumericType(category, std::move(value)); 2452 } 2453 } 2454 2455 const DeclTypeSpec &ScopeHandler::MakeLogicalType( 2456 const std::optional<parser::KindSelector> &kind) { 2457 KindExpr value{GetKindParamExpr(TypeCategory::Logical, kind)}; 2458 if (auto known{evaluate::ToInt64(value)}) { 2459 return context().MakeLogicalType(static_cast<int>(*known)); 2460 } else { 2461 return currScope_->MakeLogicalType(std::move(value)); 2462 } 2463 } 2464 2465 void ScopeHandler::NotePossibleBadForwardRef(const parser::Name &name) { 2466 if (inSpecificationPart_ && name.symbol) { 2467 auto kind{currScope().kind()}; 2468 if ((kind == Scope::Kind::Subprogram && !currScope().IsStmtFunction()) || 2469 kind == Scope::Kind::Block) { 2470 bool isHostAssociated{&name.symbol->owner() == &currScope() 2471 ? name.symbol->has<HostAssocDetails>() 2472 : name.symbol->owner().Contains(currScope())}; 2473 if (isHostAssociated) { 2474 specPartState_.forwardRefs.insert(name.source); 2475 } 2476 } 2477 } 2478 } 2479 2480 std::optional<SourceName> ScopeHandler::HadForwardRef( 2481 const Symbol &symbol) const { 2482 auto iter{specPartState_.forwardRefs.find(symbol.name())}; 2483 if (iter != specPartState_.forwardRefs.end()) { 2484 return *iter; 2485 } 2486 return std::nullopt; 2487 } 2488 2489 bool ScopeHandler::CheckPossibleBadForwardRef(const Symbol &symbol) { 2490 if (!context().HasError(symbol)) { 2491 if (auto fwdRef{HadForwardRef(symbol)}) { 2492 const Symbol *outer{symbol.owner().FindSymbol(symbol.name())}; 2493 if (outer && symbol.has<UseDetails>() && 2494 &symbol.GetUltimate() == &outer->GetUltimate()) { 2495 // e.g. IMPORT of host's USE association 2496 return false; 2497 } 2498 Say(*fwdRef, 2499 "Forward reference to '%s' is not allowed in the same specification part"_err_en_US, 2500 *fwdRef) 2501 .Attach(symbol.name(), "Later declaration of '%s'"_en_US, *fwdRef); 2502 context().SetError(symbol); 2503 return true; 2504 } 2505 if (IsDummy(symbol) && isImplicitNoneType() && 2506 symbol.test(Symbol::Flag::Implicit) && !context().HasError(symbol)) { 2507 // Dummy was implicitly typed despite IMPLICIT NONE(TYPE) in 2508 // ApplyImplicitRules() due to use in a specification expression, 2509 // and no explicit type declaration appeared later. 2510 Say(symbol.name(), 2511 "No explicit type declared for dummy argument '%s'"_err_en_US); 2512 context().SetError(symbol); 2513 return true; 2514 } 2515 } 2516 return false; 2517 } 2518 2519 void ScopeHandler::MakeExternal(Symbol &symbol) { 2520 if (!symbol.attrs().test(Attr::EXTERNAL)) { 2521 symbol.attrs().set(Attr::EXTERNAL); 2522 if (symbol.attrs().test(Attr::INTRINSIC)) { // C840 2523 Say(symbol.name(), 2524 "Symbol '%s' cannot have both EXTERNAL and INTRINSIC attributes"_err_en_US, 2525 symbol.name()); 2526 } 2527 } 2528 } 2529 2530 // ModuleVisitor implementation 2531 2532 bool ModuleVisitor::Pre(const parser::Only &x) { 2533 common::visit(common::visitors{ 2534 [&](const Indirection<parser::GenericSpec> &generic) { 2535 GenericSpecInfo genericSpecInfo{generic.value()}; 2536 AddUseOnly(genericSpecInfo.symbolName()); 2537 AddUse(genericSpecInfo); 2538 }, 2539 [&](const parser::Name &name) { 2540 AddUseOnly(name.source); 2541 Resolve(name, AddUse(name.source, name.source).use); 2542 }, 2543 [&](const parser::Rename &rename) { Walk(rename); }, 2544 }, 2545 x.u); 2546 return false; 2547 } 2548 2549 bool ModuleVisitor::Pre(const parser::Rename::Names &x) { 2550 const auto &localName{std::get<0>(x.t)}; 2551 const auto &useName{std::get<1>(x.t)}; 2552 AddUseRename(useName.source); 2553 SymbolRename rename{AddUse(localName.source, useName.source)}; 2554 if (rename.use) { 2555 EraseRenamedSymbol(*rename.use); 2556 } 2557 Resolve(useName, rename.use); 2558 Resolve(localName, rename.local); 2559 return false; 2560 } 2561 bool ModuleVisitor::Pre(const parser::Rename::Operators &x) { 2562 const parser::DefinedOpName &local{std::get<0>(x.t)}; 2563 const parser::DefinedOpName &use{std::get<1>(x.t)}; 2564 GenericSpecInfo localInfo{local}; 2565 GenericSpecInfo useInfo{use}; 2566 if (IsIntrinsicOperator(context(), local.v.source)) { 2567 Say(local.v, 2568 "Intrinsic operator '%s' may not be used as a defined operator"_err_en_US); 2569 } else if (IsLogicalConstant(context(), local.v.source)) { 2570 Say(local.v, 2571 "Logical constant '%s' may not be used as a defined operator"_err_en_US); 2572 } else { 2573 SymbolRename rename{AddUse(localInfo.symbolName(), useInfo.symbolName())}; 2574 if (rename.use) { 2575 EraseRenamedSymbol(*rename.use); 2576 } 2577 useInfo.Resolve(rename.use); 2578 localInfo.Resolve(rename.local); 2579 } 2580 return false; 2581 } 2582 2583 // Set useModuleScope_ to the Scope of the module being used. 2584 bool ModuleVisitor::Pre(const parser::UseStmt &x) { 2585 std::optional<bool> isIntrinsic; 2586 if (x.nature) { 2587 isIntrinsic = *x.nature == parser::UseStmt::ModuleNature::Intrinsic; 2588 AddAndCheckExplicitIntrinsicUse(x.moduleName.source, *isIntrinsic); 2589 } else if (currScope().IsModule() && currScope().symbol() && 2590 currScope().symbol()->attrs().test(Attr::INTRINSIC)) { 2591 // Intrinsic modules USE only other intrinsic modules 2592 isIntrinsic = true; 2593 } 2594 useModuleScope_ = FindModule(x.moduleName, isIntrinsic); 2595 if (!useModuleScope_) { 2596 return false; 2597 } 2598 // use the name from this source file 2599 useModuleScope_->symbol()->ReplaceName(x.moduleName.source); 2600 return true; 2601 } 2602 2603 void ModuleVisitor::Post(const parser::UseStmt &x) { 2604 if (const auto *list{std::get_if<std::list<parser::Rename>>(&x.u)}) { 2605 // Not a use-only: collect the names that were used in renames, 2606 // then add a use for each public name that was not renamed. 2607 std::set<SourceName> useNames; 2608 for (const auto &rename : *list) { 2609 common::visit(common::visitors{ 2610 [&](const parser::Rename::Names &names) { 2611 useNames.insert(std::get<1>(names.t).source); 2612 }, 2613 [&](const parser::Rename::Operators &ops) { 2614 useNames.insert(std::get<1>(ops.t).v.source); 2615 }, 2616 }, 2617 rename.u); 2618 } 2619 for (const auto &[name, symbol] : *useModuleScope_) { 2620 if (symbol->attrs().test(Attr::PUBLIC) && !IsUseRenamed(symbol->name()) && 2621 (!symbol->attrs().test(Attr::INTRINSIC) || 2622 symbol->has<UseDetails>()) && 2623 !symbol->has<MiscDetails>() && useNames.count(name) == 0) { 2624 SourceName location{x.moduleName.source}; 2625 if (auto *localSymbol{FindInScope(name)}) { 2626 DoAddUse(location, localSymbol->name(), *localSymbol, *symbol); 2627 } else { 2628 DoAddUse(location, location, CopySymbol(name, *symbol), *symbol); 2629 } 2630 } 2631 } 2632 } 2633 useModuleScope_ = nullptr; 2634 } 2635 2636 ModuleVisitor::SymbolRename ModuleVisitor::AddUse( 2637 const SourceName &localName, const SourceName &useName) { 2638 return AddUse(localName, useName, FindInScope(*useModuleScope_, useName)); 2639 } 2640 2641 ModuleVisitor::SymbolRename ModuleVisitor::AddUse( 2642 const SourceName &localName, const SourceName &useName, Symbol *useSymbol) { 2643 if (!useModuleScope_) { 2644 return {}; // error occurred finding module 2645 } 2646 if (!useSymbol) { 2647 Say(useName, "'%s' not found in module '%s'"_err_en_US, MakeOpName(useName), 2648 useModuleScope_->GetName().value()); 2649 return {}; 2650 } 2651 if (useSymbol->attrs().test(Attr::PRIVATE) && 2652 !FindModuleFileContaining(currScope())) { 2653 // Privacy is not enforced in module files so that generic interfaces 2654 // can be resolved to private specific procedures in specification 2655 // expressions. 2656 Say(useName, "'%s' is PRIVATE in '%s'"_err_en_US, MakeOpName(useName), 2657 useModuleScope_->GetName().value()); 2658 return {}; 2659 } 2660 auto &localSymbol{MakeSymbol(localName)}; 2661 DoAddUse(useName, localName, localSymbol, *useSymbol); 2662 return {&localSymbol, useSymbol}; 2663 } 2664 2665 // symbol must be either a Use or a Generic formed by merging two uses. 2666 // Convert it to a UseError with this additional location. 2667 static void ConvertToUseError( 2668 Symbol &symbol, const SourceName &location, const Scope &module) { 2669 const auto *useDetails{symbol.detailsIf<UseDetails>()}; 2670 if (!useDetails) { 2671 auto &genericDetails{symbol.get<GenericDetails>()}; 2672 useDetails = &genericDetails.uses().at(0)->get<UseDetails>(); 2673 } 2674 symbol.set_details( 2675 UseErrorDetails{*useDetails}.add_occurrence(location, module)); 2676 } 2677 2678 // If a symbol has previously been USE-associated and did not appear in a USE 2679 // ONLY clause, erase it from the current scope. This is needed when a name 2680 // appears in a USE rename clause. 2681 void ModuleVisitor::EraseRenamedSymbol(const Symbol &useSymbol) { 2682 const SourceName &name{useSymbol.name()}; 2683 if (const Symbol * symbol{FindInScope(name)}) { 2684 if (auto *useDetails{symbol->detailsIf<UseDetails>()}) { 2685 const Symbol &moduleSymbol{useDetails->symbol()}; 2686 if (moduleSymbol.name() == name && 2687 moduleSymbol.owner() == useSymbol.owner() && IsUseRenamed(name) && 2688 !IsUseOnly(name)) { 2689 EraseSymbol(*symbol); 2690 } 2691 } 2692 } 2693 } 2694 2695 void ModuleVisitor::DoAddUse(SourceName location, SourceName localName, 2696 Symbol &localSymbol, const Symbol &useSymbol) { 2697 if (localName != useSymbol.name()) { 2698 EraseRenamedSymbol(useSymbol); 2699 } 2700 if (auto *details{localSymbol.detailsIf<UseErrorDetails>()}) { 2701 details->add_occurrence(location, *useModuleScope_); 2702 return; 2703 } 2704 2705 if (localSymbol.has<UnknownDetails>()) { 2706 localSymbol.set_details(UseDetails{localName, useSymbol}); 2707 localSymbol.attrs() = 2708 useSymbol.attrs() & ~Attrs{Attr::PUBLIC, Attr::PRIVATE}; 2709 localSymbol.flags() = useSymbol.flags(); 2710 return; 2711 } 2712 2713 Symbol &localUltimate{localSymbol.GetUltimate()}; 2714 const Symbol &useUltimate{useSymbol.GetUltimate()}; 2715 if (&localUltimate == &useUltimate) { 2716 // use-associating the same symbol again -- ok 2717 return; 2718 } 2719 2720 auto checkAmbiguousDerivedType{[this, location, localName]( 2721 const Symbol *t1, const Symbol *t2) { 2722 if (!t1 || !t2) { 2723 return true; 2724 } else { 2725 t1 = &t1->GetUltimate(); 2726 t2 = &t2->GetUltimate(); 2727 if (&t1 != &t2) { 2728 Say(location, 2729 "Generic interface '%s' has ambiguous derived types from modules '%s' and '%s'"_err_en_US, 2730 localName, t1->owner().GetName().value(), 2731 t2->owner().GetName().value()); 2732 return false; 2733 } 2734 } 2735 }}; 2736 2737 auto *localGeneric{localUltimate.detailsIf<GenericDetails>()}; 2738 const auto *useGeneric{useUltimate.detailsIf<GenericDetails>()}; 2739 auto combine{false}; 2740 if (localGeneric) { 2741 if (useGeneric) { 2742 if (!checkAmbiguousDerivedType( 2743 localGeneric->derivedType(), useGeneric->derivedType())) { 2744 return; 2745 } 2746 combine = true; 2747 } else if (useUltimate.has<DerivedTypeDetails>()) { 2748 if (checkAmbiguousDerivedType( 2749 &useUltimate, localGeneric->derivedType())) { 2750 combine = true; 2751 } else { 2752 return; 2753 } 2754 } else if (&useUltimate == &BypassGeneric(localUltimate)) { 2755 return; // nothing to do; used subprogram is local's specific 2756 } 2757 } else if (useGeneric) { 2758 if (localUltimate.has<DerivedTypeDetails>()) { 2759 if (checkAmbiguousDerivedType( 2760 &localUltimate, useGeneric->derivedType())) { 2761 combine = true; 2762 } else { 2763 return; 2764 } 2765 } else if (&localUltimate == &BypassGeneric(useUltimate).GetUltimate()) { 2766 // Local is the specific of the used generic; replace it. 2767 EraseSymbol(localSymbol); 2768 Symbol &newSymbol{MakeSymbol(localName, 2769 useUltimate.attrs() & ~Attrs{Attr::PUBLIC, Attr::PRIVATE}, 2770 UseDetails{localName, useUltimate})}; 2771 newSymbol.flags() = useSymbol.flags(); 2772 return; 2773 } 2774 } 2775 if (!combine) { 2776 if (localSymbol.has<UseDetails>() || localSymbol.has<GenericDetails>()) { 2777 ConvertToUseError(localSymbol, location, *useModuleScope_); 2778 } else { 2779 Say(location, 2780 "Cannot use-associate '%s'; it is already declared in this scope"_err_en_US, 2781 localName) 2782 .Attach(localSymbol.name(), "Previous declaration of '%s'"_en_US, 2783 localName); 2784 } 2785 return; 2786 } 2787 2788 // Two items are being use-associated from different modules 2789 // to the same local name. At least one of them must be a generic, 2790 // and the other one can be a generic or a derived type. 2791 // (It could also have been the specific of the generic, but those 2792 // cases are handled above without needing to make a local copy of the 2793 // generic.) 2794 2795 if (localGeneric) { 2796 if (localSymbol.has<UseDetails>()) { 2797 // Create a local copy of a previously use-associated generic so that 2798 // it can be locally extended without corrupting the original. 2799 GenericDetails generic; 2800 generic.CopyFrom(*localGeneric); 2801 EraseSymbol(localSymbol); 2802 Symbol &newSymbol{MakeSymbol( 2803 localSymbol.name(), localSymbol.attrs(), std::move(generic))}; 2804 newSymbol.flags() = localSymbol.flags(); 2805 localGeneric = &newSymbol.get<GenericDetails>(); 2806 localGeneric->AddUse(localSymbol); 2807 } 2808 if (useGeneric) { 2809 // Combine two use-associated generics 2810 localSymbol.attrs() = 2811 useSymbol.attrs() & ~Attrs{Attr::PUBLIC, Attr::PRIVATE}; 2812 localSymbol.flags() = useSymbol.flags(); 2813 AddGenericUse(*localGeneric, localName, useUltimate); 2814 localGeneric->CopyFrom(*useGeneric); 2815 } else { 2816 CHECK(useUltimate.has<DerivedTypeDetails>()); 2817 localGeneric->set_derivedType( 2818 AddGenericUse(*localGeneric, localName, useUltimate)); 2819 } 2820 } else { 2821 CHECK(useGeneric && localUltimate.has<DerivedTypeDetails>()); 2822 CHECK(localSymbol.has<UseDetails>()); 2823 // Create a local copy of the use-associated generic, then extend it 2824 // with the local derived type. 2825 GenericDetails generic; 2826 generic.CopyFrom(*useGeneric); 2827 EraseSymbol(localSymbol); 2828 Symbol &newSymbol{MakeSymbol(localName, 2829 useUltimate.attrs() & ~Attrs{Attr::PUBLIC, Attr::PRIVATE}, 2830 std::move(generic))}; 2831 newSymbol.flags() = useUltimate.flags(); 2832 auto &newUseGeneric{newSymbol.get<GenericDetails>()}; 2833 AddGenericUse(newUseGeneric, localName, useUltimate); 2834 newUseGeneric.AddUse(localSymbol); 2835 newUseGeneric.set_derivedType(localSymbol); 2836 } 2837 } 2838 2839 void ModuleVisitor::AddUse(const GenericSpecInfo &info) { 2840 if (useModuleScope_) { 2841 const auto &name{info.symbolName()}; 2842 auto rename{AddUse(name, name, FindInScope(*useModuleScope_, name))}; 2843 info.Resolve(rename.use); 2844 } 2845 } 2846 2847 // Create a UseDetails symbol for this USE and add it to generic 2848 Symbol &ModuleVisitor::AddGenericUse( 2849 GenericDetails &generic, const SourceName &name, const Symbol &useSymbol) { 2850 Symbol &newSymbol{ 2851 currScope().MakeSymbol(name, {}, UseDetails{name, useSymbol})}; 2852 generic.AddUse(newSymbol); 2853 return newSymbol; 2854 } 2855 2856 // Enforce C1406 2857 void ModuleVisitor::AddAndCheckExplicitIntrinsicUse( 2858 SourceName name, bool isIntrinsic) { 2859 if (isIntrinsic) { 2860 if (auto iter{explicitNonIntrinsicUses_.find(name)}; 2861 iter != explicitNonIntrinsicUses_.end()) { 2862 Say(name, 2863 "Cannot USE,INTRINSIC module '%s' in the same scope as USE,NON_INTRINSIC"_err_en_US, 2864 name) 2865 .Attach(*iter, "Previous USE of '%s'"_en_US, *iter); 2866 } 2867 explicitIntrinsicUses_.insert(name); 2868 } else { 2869 if (auto iter{explicitIntrinsicUses_.find(name)}; 2870 iter != explicitIntrinsicUses_.end()) { 2871 Say(name, 2872 "Cannot USE,NON_INTRINSIC module '%s' in the same scope as USE,INTRINSIC"_err_en_US, 2873 name) 2874 .Attach(*iter, "Previous USE of '%s'"_en_US, *iter); 2875 } 2876 explicitNonIntrinsicUses_.insert(name); 2877 } 2878 } 2879 2880 bool ModuleVisitor::BeginSubmodule( 2881 const parser::Name &name, const parser::ParentIdentifier &parentId) { 2882 auto &ancestorName{std::get<parser::Name>(parentId.t)}; 2883 auto &parentName{std::get<std::optional<parser::Name>>(parentId.t)}; 2884 Scope *ancestor{FindModule(ancestorName, false /*not intrinsic*/)}; 2885 if (!ancestor) { 2886 return false; 2887 } 2888 Scope *parentScope{parentName 2889 ? FindModule(*parentName, false /*not intrinsic*/, ancestor) 2890 : ancestor}; 2891 if (!parentScope) { 2892 return false; 2893 } 2894 PushScope(*parentScope); // submodule is hosted in parent 2895 BeginModule(name, true); 2896 if (!ancestor->AddSubmodule(name.source, currScope())) { 2897 Say(name, "Module '%s' already has a submodule named '%s'"_err_en_US, 2898 ancestorName.source, name.source); 2899 } 2900 return true; 2901 } 2902 2903 void ModuleVisitor::BeginModule(const parser::Name &name, bool isSubmodule) { 2904 auto &symbol{MakeSymbol(name, ModuleDetails{isSubmodule})}; 2905 auto &details{symbol.get<ModuleDetails>()}; 2906 PushScope(Scope::Kind::Module, &symbol); 2907 details.set_scope(&currScope()); 2908 defaultAccess_ = Attr::PUBLIC; 2909 prevAccessStmt_ = std::nullopt; 2910 } 2911 2912 // Find a module or submodule by name and return its scope. 2913 // If ancestor is present, look for a submodule of that ancestor module. 2914 // May have to read a .mod file to find it. 2915 // If an error occurs, report it and return nullptr. 2916 Scope *ModuleVisitor::FindModule(const parser::Name &name, 2917 std::optional<bool> isIntrinsic, Scope *ancestor) { 2918 ModFileReader reader{context()}; 2919 Scope *scope{reader.Read(name.source, isIntrinsic, ancestor)}; 2920 if (!scope) { 2921 return nullptr; 2922 } 2923 if (scope->kind() != Scope::Kind::Module) { 2924 Say(name, "'%s' is not a module"_err_en_US); 2925 return nullptr; 2926 } 2927 if (DoesScopeContain(scope, currScope())) { // 14.2.2(1) 2928 Say(name, "Module '%s' cannot USE itself"_err_en_US); 2929 } 2930 Resolve(name, scope->symbol()); 2931 return scope; 2932 } 2933 2934 void ModuleVisitor::ApplyDefaultAccess() { 2935 for (auto &pair : currScope()) { 2936 Symbol &symbol = *pair.second; 2937 if (!symbol.attrs().HasAny({Attr::PUBLIC, Attr::PRIVATE})) { 2938 symbol.attrs().set(defaultAccess_); 2939 } 2940 } 2941 } 2942 2943 // InterfaceVistor implementation 2944 2945 bool InterfaceVisitor::Pre(const parser::InterfaceStmt &x) { 2946 bool isAbstract{std::holds_alternative<parser::Abstract>(x.u)}; 2947 genericInfo_.emplace(/*isInterface*/ true, isAbstract); 2948 return BeginAttrs(); 2949 } 2950 2951 void InterfaceVisitor::Post(const parser::InterfaceStmt &) { EndAttrs(); } 2952 2953 void InterfaceVisitor::Post(const parser::EndInterfaceStmt &) { 2954 genericInfo_.pop(); 2955 } 2956 2957 // Create a symbol in genericSymbol_ for this GenericSpec. 2958 bool InterfaceVisitor::Pre(const parser::GenericSpec &x) { 2959 if (auto *symbol{FindInScope(GenericSpecInfo{x}.symbolName())}) { 2960 SetGenericSymbol(*symbol); 2961 } 2962 return false; 2963 } 2964 2965 bool InterfaceVisitor::Pre(const parser::ProcedureStmt &x) { 2966 if (!isGeneric()) { 2967 Say("A PROCEDURE statement is only allowed in a generic interface block"_err_en_US); 2968 return false; 2969 } 2970 auto kind{std::get<parser::ProcedureStmt::Kind>(x.t)}; 2971 const auto &names{std::get<std::list<parser::Name>>(x.t)}; 2972 AddSpecificProcs(names, kind); 2973 return false; 2974 } 2975 2976 bool InterfaceVisitor::Pre(const parser::GenericStmt &) { 2977 genericInfo_.emplace(/*isInterface*/ false); 2978 return true; 2979 } 2980 void InterfaceVisitor::Post(const parser::GenericStmt &x) { 2981 if (auto &accessSpec{std::get<std::optional<parser::AccessSpec>>(x.t)}) { 2982 GetGenericInfo().symbol->attrs().set(AccessSpecToAttr(*accessSpec)); 2983 } 2984 const auto &names{std::get<std::list<parser::Name>>(x.t)}; 2985 AddSpecificProcs(names, ProcedureKind::Procedure); 2986 genericInfo_.pop(); 2987 } 2988 2989 bool InterfaceVisitor::inInterfaceBlock() const { 2990 return !genericInfo_.empty() && GetGenericInfo().isInterface; 2991 } 2992 bool InterfaceVisitor::isGeneric() const { 2993 return !genericInfo_.empty() && GetGenericInfo().symbol; 2994 } 2995 bool InterfaceVisitor::isAbstract() const { 2996 return !genericInfo_.empty() && GetGenericInfo().isAbstract; 2997 } 2998 2999 void InterfaceVisitor::AddSpecificProcs( 3000 const std::list<parser::Name> &names, ProcedureKind kind) { 3001 for (const auto &name : names) { 3002 specificProcs_.emplace( 3003 GetGenericInfo().symbol, std::make_pair(&name, kind)); 3004 } 3005 } 3006 3007 // By now we should have seen all specific procedures referenced by name in 3008 // this generic interface. Resolve those names to symbols. 3009 void InterfaceVisitor::ResolveSpecificsInGeneric(Symbol &generic) { 3010 auto &details{generic.get<GenericDetails>()}; 3011 UnorderedSymbolSet symbolsSeen; 3012 for (const Symbol &symbol : details.specificProcs()) { 3013 symbolsSeen.insert(symbol.GetUltimate()); 3014 } 3015 auto range{specificProcs_.equal_range(&generic)}; 3016 for (auto it{range.first}; it != range.second; ++it) { 3017 const parser::Name *name{it->second.first}; 3018 auto kind{it->second.second}; 3019 const auto *symbol{FindSymbol(*name)}; 3020 if (!symbol) { 3021 Say(*name, "Procedure '%s' not found"_err_en_US); 3022 continue; 3023 } 3024 const Symbol &specific{BypassGeneric(*symbol)}; 3025 const Symbol &ultimate{specific.GetUltimate()}; 3026 if (!ultimate.has<SubprogramDetails>() && 3027 !ultimate.has<SubprogramNameDetails>()) { 3028 Say(*name, "'%s' is not a subprogram"_err_en_US); 3029 continue; 3030 } 3031 if (kind == ProcedureKind::ModuleProcedure) { 3032 if (const auto *nd{ultimate.detailsIf<SubprogramNameDetails>()}) { 3033 if (nd->kind() != SubprogramKind::Module) { 3034 Say(*name, "'%s' is not a module procedure"_err_en_US); 3035 } 3036 } else { 3037 // USE-associated procedure 3038 const auto *sd{ultimate.detailsIf<SubprogramDetails>()}; 3039 CHECK(sd); 3040 if (ultimate.owner().kind() != Scope::Kind::Module || 3041 sd->isInterface()) { 3042 Say(*name, "'%s' is not a module procedure"_err_en_US); 3043 } 3044 } 3045 } 3046 if (symbolsSeen.insert(ultimate).second /*true if added*/) { 3047 // When a specific procedure is a USE association, that association 3048 // is saved in the generic's specifics, not its ultimate symbol, 3049 // so that module file output of interfaces can distinguish them. 3050 details.AddSpecificProc(specific, name->source); 3051 } else if (&specific == &ultimate) { 3052 Say(name->source, 3053 "Procedure '%s' is already specified in generic '%s'"_err_en_US, 3054 name->source, MakeOpName(generic.name())); 3055 } else { 3056 Say(name->source, 3057 "Procedure '%s' from module '%s' is already specified in generic '%s'"_err_en_US, 3058 ultimate.name(), ultimate.owner().GetName().value(), 3059 MakeOpName(generic.name())); 3060 } 3061 } 3062 specificProcs_.erase(range.first, range.second); 3063 } 3064 3065 // Check that the specific procedures are all functions or all subroutines. 3066 // If there is a derived type with the same name they must be functions. 3067 // Set the corresponding flag on generic. 3068 void InterfaceVisitor::CheckGenericProcedures(Symbol &generic) { 3069 ResolveSpecificsInGeneric(generic); 3070 auto &details{generic.get<GenericDetails>()}; 3071 if (auto *proc{details.CheckSpecific()}) { 3072 auto msg{ 3073 "'%s' may not be the name of both a generic interface and a" 3074 " procedure unless it is a specific procedure of the generic"_err_en_US}; 3075 if (proc->name().begin() > generic.name().begin()) { 3076 Say(proc->name(), std::move(msg)); 3077 } else { 3078 Say(generic.name(), std::move(msg)); 3079 } 3080 } 3081 auto &specifics{details.specificProcs()}; 3082 if (specifics.empty()) { 3083 if (details.derivedType()) { 3084 generic.set(Symbol::Flag::Function); 3085 } 3086 return; 3087 } 3088 const Symbol &firstSpecific{specifics.front()}; 3089 bool isFunction{firstSpecific.test(Symbol::Flag::Function)}; 3090 for (const Symbol &specific : specifics) { 3091 if (isFunction != specific.test(Symbol::Flag::Function)) { // C1514 3092 auto &msg{Say(generic.name(), 3093 "Generic interface '%s' has both a function and a subroutine"_err_en_US)}; 3094 if (isFunction) { 3095 msg.Attach(firstSpecific.name(), "Function declaration"_en_US); 3096 msg.Attach(specific.name(), "Subroutine declaration"_en_US); 3097 } else { 3098 msg.Attach(firstSpecific.name(), "Subroutine declaration"_en_US); 3099 msg.Attach(specific.name(), "Function declaration"_en_US); 3100 } 3101 } 3102 } 3103 if (!isFunction && details.derivedType()) { 3104 SayDerivedType(generic.name(), 3105 "Generic interface '%s' may only contain functions due to derived type" 3106 " with same name"_err_en_US, 3107 *details.derivedType()->scope()); 3108 } 3109 generic.set(isFunction ? Symbol::Flag::Function : Symbol::Flag::Subroutine); 3110 } 3111 3112 // SubprogramVisitor implementation 3113 3114 // Return false if it is actually an assignment statement. 3115 bool SubprogramVisitor::HandleStmtFunction(const parser::StmtFunctionStmt &x) { 3116 const auto &name{std::get<parser::Name>(x.t)}; 3117 const DeclTypeSpec *resultType{nullptr}; 3118 // Look up name: provides return type or tells us if it's an array 3119 if (auto *symbol{FindSymbol(name)}) { 3120 auto *details{symbol->detailsIf<EntityDetails>()}; 3121 if (!details) { 3122 badStmtFuncFound_ = true; 3123 return false; 3124 } 3125 // TODO: check that attrs are compatible with stmt func 3126 resultType = details->type(); 3127 symbol->details() = UnknownDetails{}; // will be replaced below 3128 } 3129 if (badStmtFuncFound_) { 3130 Say(name, "'%s' has not been declared as an array"_err_en_US); 3131 return true; 3132 } 3133 auto &symbol{PushSubprogramScope(name, Symbol::Flag::Function)}; 3134 symbol.set(Symbol::Flag::StmtFunction); 3135 EraseSymbol(symbol); // removes symbol added by PushSubprogramScope 3136 auto &details{symbol.get<SubprogramDetails>()}; 3137 for (const auto &dummyName : std::get<std::list<parser::Name>>(x.t)) { 3138 ObjectEntityDetails dummyDetails{true}; 3139 if (auto *dummySymbol{FindInScope(currScope().parent(), dummyName)}) { 3140 if (auto *d{dummySymbol->detailsIf<EntityDetails>()}) { 3141 if (d->type()) { 3142 dummyDetails.set_type(*d->type()); 3143 } 3144 } 3145 } 3146 Symbol &dummy{MakeSymbol(dummyName, std::move(dummyDetails))}; 3147 ApplyImplicitRules(dummy); 3148 details.add_dummyArg(dummy); 3149 } 3150 ObjectEntityDetails resultDetails; 3151 if (resultType) { 3152 resultDetails.set_type(*resultType); 3153 } 3154 resultDetails.set_funcResult(true); 3155 Symbol &result{MakeSymbol(name, std::move(resultDetails))}; 3156 ApplyImplicitRules(result); 3157 details.set_result(result); 3158 const auto &parsedExpr{std::get<parser::Scalar<parser::Expr>>(x.t)}; 3159 Walk(parsedExpr); 3160 // The analysis of the expression that constitutes the body of the 3161 // statement function is deferred to FinishSpecificationPart() so that 3162 // all declarations and implicit typing are complete. 3163 PopScope(); 3164 return true; 3165 } 3166 3167 bool SubprogramVisitor::Pre(const parser::Suffix &suffix) { 3168 if (suffix.resultName) { 3169 if (IsFunction(currScope())) { 3170 if (FuncResultStack::FuncInfo * info{funcResultStack().Top()}) { 3171 if (info->inFunctionStmt) { 3172 info->resultName = &suffix.resultName.value(); 3173 } else { 3174 // will check the result name in Post(EntryStmt) 3175 } 3176 } 3177 } else { 3178 Message &msg{Say(*suffix.resultName, 3179 "RESULT(%s) may appear only in a function"_err_en_US)}; 3180 if (const Symbol * subprogram{InclusiveScope().symbol()}) { 3181 msg.Attach(subprogram->name(), "Containing subprogram"_en_US); 3182 } 3183 } 3184 } 3185 return true; 3186 } 3187 3188 bool SubprogramVisitor::Pre(const parser::PrefixSpec &x) { 3189 // Save this to process after UseStmt and ImplicitPart 3190 if (const auto *parsedType{std::get_if<parser::DeclarationTypeSpec>(&x.u)}) { 3191 FuncResultStack::FuncInfo &info{DEREF(funcResultStack().Top())}; 3192 if (info.parsedType) { // C1543 3193 Say(currStmtSource().value(), 3194 "FUNCTION prefix cannot specify the type more than once"_err_en_US); 3195 return false; 3196 } else { 3197 info.parsedType = parsedType; 3198 info.source = currStmtSource(); 3199 return false; 3200 } 3201 } else { 3202 return true; 3203 } 3204 } 3205 3206 bool SubprogramVisitor::Pre(const parser::InterfaceBody::Subroutine &x) { 3207 const auto &name{std::get<parser::Name>( 3208 std::get<parser::Statement<parser::SubroutineStmt>>(x.t).statement.t)}; 3209 return BeginSubprogram(name, Symbol::Flag::Subroutine); 3210 } 3211 void SubprogramVisitor::Post(const parser::InterfaceBody::Subroutine &) { 3212 EndSubprogram(); 3213 } 3214 bool SubprogramVisitor::Pre(const parser::InterfaceBody::Function &x) { 3215 const auto &name{std::get<parser::Name>( 3216 std::get<parser::Statement<parser::FunctionStmt>>(x.t).statement.t)}; 3217 return BeginSubprogram(name, Symbol::Flag::Function); 3218 } 3219 void SubprogramVisitor::Post(const parser::InterfaceBody::Function &) { 3220 EndSubprogram(); 3221 } 3222 3223 bool SubprogramVisitor::Pre(const parser::SubroutineStmt &) { 3224 return BeginAttrs(); 3225 } 3226 bool SubprogramVisitor::Pre(const parser::FunctionStmt &) { 3227 FuncResultStack::FuncInfo &info{DEREF(funcResultStack().Top())}; 3228 CHECK(!info.inFunctionStmt); 3229 info.inFunctionStmt = true; 3230 return BeginAttrs(); 3231 } 3232 bool SubprogramVisitor::Pre(const parser::EntryStmt &) { return BeginAttrs(); } 3233 3234 void SubprogramVisitor::Post(const parser::SubroutineStmt &stmt) { 3235 const auto &name{std::get<parser::Name>(stmt.t)}; 3236 auto &details{PostSubprogramStmt(name)}; 3237 for (const auto &dummyArg : std::get<std::list<parser::DummyArg>>(stmt.t)) { 3238 if (const auto *dummyName{std::get_if<parser::Name>(&dummyArg.u)}) { 3239 Symbol &dummy{MakeSymbol(*dummyName, EntityDetails{true})}; 3240 details.add_dummyArg(dummy); 3241 } else { 3242 details.add_alternateReturn(); 3243 } 3244 } 3245 } 3246 3247 void SubprogramVisitor::Post(const parser::FunctionStmt &stmt) { 3248 const auto &name{std::get<parser::Name>(stmt.t)}; 3249 auto &details{PostSubprogramStmt(name)}; 3250 for (const auto &dummyName : std::get<std::list<parser::Name>>(stmt.t)) { 3251 Symbol &dummy{MakeSymbol(dummyName, EntityDetails{true})}; 3252 details.add_dummyArg(dummy); 3253 } 3254 const parser::Name *funcResultName; 3255 FuncResultStack::FuncInfo &info{DEREF(funcResultStack().Top())}; 3256 CHECK(info.inFunctionStmt); 3257 info.inFunctionStmt = false; 3258 if (info.resultName && info.resultName->source != name.source) { 3259 // Note that RESULT is ignored if it has the same name as the function. 3260 funcResultName = info.resultName; 3261 } else { 3262 EraseSymbol(name); // was added by PushSubprogramScope 3263 funcResultName = &name; 3264 } 3265 // add function result to function scope 3266 if (details.isFunction()) { 3267 CHECK(context().HasError(currScope().symbol())); 3268 } else { 3269 // add function result to function scope 3270 EntityDetails funcResultDetails; 3271 funcResultDetails.set_funcResult(true); 3272 Symbol &result{MakeSymbol(*funcResultName, std::move(funcResultDetails))}; 3273 info.resultSymbol = &result; 3274 details.set_result(result); 3275 } 3276 // C1560. 3277 if (info.resultName && info.resultName->source == name.source) { 3278 Say(info.resultName->source, 3279 "The function name should not appear in RESULT, references to '%s' " 3280 "inside the function will be considered as references to the " 3281 "result only"_warn_en_US, 3282 name.source); 3283 // RESULT name was ignored above, the only side effect from doing so will be 3284 // the inability to make recursive calls. The related parser::Name is still 3285 // resolved to the created function result symbol because every parser::Name 3286 // should be resolved to avoid internal errors. 3287 Resolve(*info.resultName, info.resultSymbol); 3288 } 3289 name.symbol = currScope().symbol(); // must not be function result symbol 3290 // Clear the RESULT() name now in case an ENTRY statement in the implicit-part 3291 // has a RESULT() suffix. 3292 info.resultName = nullptr; 3293 } 3294 3295 SubprogramDetails &SubprogramVisitor::PostSubprogramStmt( 3296 const parser::Name &name) { 3297 Symbol &symbol{*currScope().symbol()}; 3298 CHECK(name.source == symbol.name()); 3299 SetBindNameOn(symbol); 3300 symbol.attrs() |= EndAttrs(); 3301 if (symbol.attrs().test(Attr::MODULE)) { 3302 symbol.attrs().set(Attr::EXTERNAL, false); 3303 } 3304 return symbol.get<SubprogramDetails>(); 3305 } 3306 3307 void SubprogramVisitor::Post(const parser::EntryStmt &stmt) { 3308 auto attrs{EndAttrs()}; // needs to be called even if early return 3309 Scope &inclusiveScope{InclusiveScope()}; 3310 const Symbol *subprogram{inclusiveScope.symbol()}; 3311 if (!subprogram) { 3312 CHECK(context().AnyFatalError()); 3313 return; 3314 } 3315 const auto &name{std::get<parser::Name>(stmt.t)}; 3316 const parser::Name *resultName{nullptr}; 3317 if (const auto &maybeSuffix{ 3318 std::get<std::optional<parser::Suffix>>(stmt.t)}) { 3319 resultName = common::GetPtrFromOptional(maybeSuffix->resultName); 3320 } 3321 bool inFunction{IsFunction(currScope())}; 3322 if (resultName) { // RESULT(result) is present 3323 if (!inFunction) { 3324 // error was already emitted for the suffix 3325 } else if (resultName->source == subprogram->name()) { // C1574 3326 Say2(resultName->source, 3327 "RESULT(%s) may not have the same name as the function"_err_en_US, 3328 subprogram->name(), "Containing function"_en_US); 3329 } else if (const Symbol * 3330 symbol{FindSymbol(inclusiveScope.parent(), *resultName)}) { // C1574 3331 if (const auto *details{symbol->detailsIf<SubprogramDetails>()}) { 3332 if (details->entryScope() == &inclusiveScope) { 3333 Say2(resultName->source, 3334 "RESULT(%s) may not have the same name as an ENTRY in the function"_err_en_US, 3335 symbol->name(), "Conflicting ENTRY"_en_US); 3336 } 3337 } 3338 } 3339 if (Symbol * symbol{FindSymbol(name)}) { // C1570 3340 // When RESULT() appears, ENTRY name can't have been already declared 3341 if (inclusiveScope.Contains(symbol->owner())) { 3342 Say2(name, 3343 "ENTRY name '%s' may not be declared when RESULT() is present"_err_en_US, 3344 *symbol, "Previous declaration of '%s'"_en_US); 3345 } 3346 } 3347 if (resultName->source == name.source) { 3348 // ignore RESULT() hereafter when it's the same name as the ENTRY 3349 resultName = nullptr; 3350 } 3351 } 3352 SubprogramDetails entryDetails; 3353 entryDetails.set_entryScope(inclusiveScope); 3354 if (inFunction) { 3355 // Create the entity to hold the function result, if necessary. 3356 Symbol *resultSymbol{nullptr}; 3357 auto &effectiveResultName{*(resultName ? resultName : &name)}; 3358 resultSymbol = FindInScope(currScope(), effectiveResultName); 3359 if (resultSymbol) { // C1574 3360 common::visit( 3361 common::visitors{[](EntityDetails &x) { x.set_funcResult(true); }, 3362 [](ObjectEntityDetails &x) { x.set_funcResult(true); }, 3363 [](ProcEntityDetails &x) { x.set_funcResult(true); }, 3364 [&](const auto &) { 3365 Say2(effectiveResultName.source, 3366 "'%s' was previously declared as an item that may not be used as a function result"_err_en_US, 3367 resultSymbol->name(), "Previous declaration of '%s'"_en_US); 3368 context().SetError(*resultSymbol); 3369 }}, 3370 resultSymbol->details()); 3371 } else if (inExecutionPart_) { 3372 ObjectEntityDetails entity; 3373 entity.set_funcResult(true); 3374 resultSymbol = &MakeSymbol(effectiveResultName, std::move(entity)); 3375 ApplyImplicitRules(*resultSymbol); 3376 } else { 3377 EntityDetails entity; 3378 entity.set_funcResult(true); 3379 resultSymbol = &MakeSymbol(effectiveResultName, std::move(entity)); 3380 } 3381 if (!resultName) { 3382 name.symbol = nullptr; // symbol will be used for entry point below 3383 } 3384 entryDetails.set_result(*resultSymbol); 3385 } 3386 3387 for (const auto &dummyArg : std::get<std::list<parser::DummyArg>>(stmt.t)) { 3388 if (const auto *dummyName{std::get_if<parser::Name>(&dummyArg.u)}) { 3389 Symbol *dummy{FindSymbol(*dummyName)}; 3390 if (dummy) { 3391 common::visit( 3392 common::visitors{[](EntityDetails &x) { x.set_isDummy(); }, 3393 [](ObjectEntityDetails &x) { x.set_isDummy(); }, 3394 [](ProcEntityDetails &x) { x.set_isDummy(); }, 3395 [](SubprogramDetails &x) { x.set_isDummy(); }, 3396 [&](const auto &) { 3397 Say2(dummyName->source, 3398 "ENTRY dummy argument '%s' is previously declared as an item that may not be used as a dummy argument"_err_en_US, 3399 dummy->name(), "Previous declaration of '%s'"_en_US); 3400 }}, 3401 dummy->details()); 3402 } else { 3403 dummy = &MakeSymbol(*dummyName, EntityDetails{true}); 3404 if (inExecutionPart_) { 3405 ApplyImplicitRules(*dummy); 3406 } 3407 } 3408 entryDetails.add_dummyArg(*dummy); 3409 } else { 3410 if (inFunction) { // C1573 3411 Say(name, 3412 "ENTRY in a function may not have an alternate return dummy argument"_err_en_US); 3413 break; 3414 } 3415 entryDetails.add_alternateReturn(); 3416 } 3417 } 3418 3419 Symbol::Flag subpFlag{ 3420 inFunction ? Symbol::Flag::Function : Symbol::Flag::Subroutine}; 3421 Scope &outer{inclusiveScope.parent()}; // global or module scope 3422 if (outer.IsModule() && !attrs.test(Attr::PRIVATE)) { 3423 attrs.set(Attr::PUBLIC); 3424 } 3425 if (Symbol * extant{FindSymbol(outer, name)}) { 3426 if (!HandlePreviousCalls(name, *extant, subpFlag)) { 3427 if (outer.IsGlobal()) { 3428 Say2(name, "'%s' is already defined as a global identifier"_err_en_US, 3429 *extant, "Previous definition of '%s'"_en_US); 3430 } else { 3431 SayAlreadyDeclared(name, *extant); 3432 } 3433 return; 3434 } 3435 } 3436 3437 Symbol *entrySymbol{&MakeSymbol(outer, name.source, attrs)}; 3438 if (auto *generic{entrySymbol->detailsIf<GenericDetails>()}) { 3439 CHECK(generic->specific()); 3440 entrySymbol = generic->specific(); 3441 } 3442 entrySymbol->set_details(std::move(entryDetails)); 3443 SetBindNameOn(*entrySymbol); 3444 entrySymbol->set(subpFlag); 3445 Resolve(name, *entrySymbol); 3446 } 3447 3448 // A subprogram declared with MODULE PROCEDURE 3449 bool SubprogramVisitor::BeginMpSubprogram(const parser::Name &name) { 3450 auto *symbol{FindSymbol(name)}; 3451 if (symbol && symbol->has<SubprogramNameDetails>()) { 3452 symbol = FindSymbol(currScope().parent(), name); 3453 } 3454 if (!IsSeparateModuleProcedureInterface(symbol)) { 3455 Say(name, "'%s' was not declared a separate module procedure"_err_en_US); 3456 return false; 3457 } 3458 if (symbol->owner() == currScope() && symbol->scope()) { 3459 // This is a MODULE PROCEDURE whose interface appears in its host. 3460 // Convert the module procedure's interface into a subprogram. 3461 SetScope(DEREF(symbol->scope())); 3462 symbol->get<SubprogramDetails>().set_isInterface(false); 3463 if (IsFunction(*symbol)) { 3464 funcResultStack().Push(); // just to be popped later 3465 } 3466 } else { 3467 // Copy the interface into a new subprogram scope. 3468 Symbol &newSymbol{MakeSymbol(name, SubprogramDetails{})}; 3469 PushScope(Scope::Kind::Subprogram, &newSymbol); 3470 const auto &details{symbol->get<SubprogramDetails>()}; 3471 auto &newDetails{newSymbol.get<SubprogramDetails>()}; 3472 newDetails.set_moduleInterface(*symbol); 3473 for (const Symbol *dummyArg : details.dummyArgs()) { 3474 if (!dummyArg) { 3475 newDetails.add_alternateReturn(); 3476 } else if (Symbol * copy{currScope().CopySymbol(*dummyArg)}) { 3477 newDetails.add_dummyArg(*copy); 3478 } 3479 } 3480 if (details.isFunction()) { 3481 currScope().erase(symbol->name()); 3482 newDetails.set_result(*currScope().CopySymbol(details.result())); 3483 funcResultStack().Push(); // just to be popped later 3484 } 3485 } 3486 return true; 3487 } 3488 3489 // A subprogram or interface declared with SUBROUTINE or FUNCTION 3490 bool SubprogramVisitor::BeginSubprogram( 3491 const parser::Name &name, Symbol::Flag subpFlag, bool hasModulePrefix) { 3492 if (hasModulePrefix && currScope().IsGlobal()) { // C1547 3493 Say(name, 3494 "'%s' is a MODULE procedure which must be declared within a " 3495 "MODULE or SUBMODULE"_err_en_US); 3496 return false; 3497 } 3498 Symbol *moduleInterface{nullptr}; 3499 if (hasModulePrefix && !inInterfaceBlock()) { 3500 moduleInterface = FindSymbol(currScope(), name); 3501 if (IsSeparateModuleProcedureInterface(moduleInterface)) { 3502 // Subprogram is MODULE FUNCTION or MODULE SUBROUTINE with an interface 3503 // previously defined in the same scope. 3504 currScope().erase(moduleInterface->name()); 3505 } else { 3506 moduleInterface = nullptr; 3507 } 3508 if (!moduleInterface) { 3509 moduleInterface = FindSymbol(currScope().parent(), name); 3510 if (!IsSeparateModuleProcedureInterface(moduleInterface)) { 3511 Say(name, 3512 "'%s' was not declared a separate module procedure"_err_en_US); 3513 return false; 3514 } 3515 } 3516 } 3517 Symbol &newSymbol{PushSubprogramScope(name, subpFlag)}; 3518 if (moduleInterface) { 3519 newSymbol.get<SubprogramDetails>().set_moduleInterface(*moduleInterface); 3520 if (moduleInterface->attrs().test(Attr::PRIVATE)) { 3521 newSymbol.attrs().set(Attr::PRIVATE); 3522 } else if (moduleInterface->attrs().test(Attr::PUBLIC)) { 3523 newSymbol.attrs().set(Attr::PUBLIC); 3524 } 3525 } 3526 if (IsFunction(currScope())) { 3527 funcResultStack().Push(); 3528 } 3529 return true; 3530 } 3531 3532 void SubprogramVisitor::EndSubprogram() { 3533 if (IsFunction(currScope())) { 3534 funcResultStack().Pop(); 3535 } 3536 PopScope(); 3537 } 3538 3539 bool SubprogramVisitor::HandlePreviousCalls( 3540 const parser::Name &name, Symbol &symbol, Symbol::Flag subpFlag) { 3541 // If the extant symbol is a generic, check its homonymous specific 3542 // procedure instead if it has one. 3543 if (auto *generic{symbol.detailsIf<GenericDetails>()}) { 3544 return generic->specific() && 3545 HandlePreviousCalls(name, *generic->specific(), subpFlag); 3546 } else if (const auto *proc{symbol.detailsIf<ProcEntityDetails>()}; proc && 3547 !proc->isDummy() && 3548 !symbol.attrs().HasAny(Attrs{Attr::INTRINSIC, Attr::POINTER})) { 3549 // There's a symbol created for previous calls to this subprogram or 3550 // ENTRY's name. We have to replace that symbol in situ to avoid the 3551 // obligation to rewrite symbol pointers in the parse tree. 3552 if (!symbol.test(subpFlag)) { 3553 Say2(name, 3554 subpFlag == Symbol::Flag::Function 3555 ? "'%s' was previously called as a subroutine"_err_en_US 3556 : "'%s' was previously called as a function"_err_en_US, 3557 symbol, "Previous call of '%s'"_en_US); 3558 } 3559 EntityDetails entity; 3560 if (proc->type()) { 3561 entity.set_type(*proc->type()); 3562 } 3563 symbol.details() = std::move(entity); 3564 return true; 3565 } else { 3566 return symbol.has<UnknownDetails>() || symbol.has<SubprogramNameDetails>(); 3567 } 3568 } 3569 3570 void SubprogramVisitor::CheckExtantProc( 3571 const parser::Name &name, Symbol::Flag subpFlag) { 3572 if (auto *prev{FindSymbol(name)}) { 3573 if (IsDummy(*prev)) { 3574 } else if (inInterfaceBlock() && currScope() != prev->owner()) { 3575 // Procedures in an INTERFACE block do not resolve to symbols 3576 // in scopes between the global scope and the current scope. 3577 } else if (!HandlePreviousCalls(name, *prev, subpFlag)) { 3578 SayAlreadyDeclared(name, *prev); 3579 } 3580 } 3581 } 3582 3583 Symbol &SubprogramVisitor::PushSubprogramScope( 3584 const parser::Name &name, Symbol::Flag subpFlag) { 3585 auto *symbol{GetSpecificFromGeneric(name)}; 3586 if (!symbol) { 3587 CheckExtantProc(name, subpFlag); 3588 symbol = &MakeSymbol(name, SubprogramDetails{}); 3589 } 3590 symbol->set(subpFlag); 3591 symbol->ReplaceName(name.source); 3592 PushScope(Scope::Kind::Subprogram, symbol); 3593 auto &details{symbol->get<SubprogramDetails>()}; 3594 if (inInterfaceBlock()) { 3595 details.set_isInterface(); 3596 if (isAbstract()) { 3597 symbol->attrs().set(Attr::ABSTRACT); 3598 } else { 3599 MakeExternal(*symbol); 3600 } 3601 if (isGeneric()) { 3602 Symbol &genericSymbol{GetGenericSymbol()}; 3603 if (genericSymbol.has<GenericDetails>()) { 3604 genericSymbol.get<GenericDetails>().AddSpecificProc( 3605 *symbol, name.source); 3606 } else { 3607 CHECK(context().HasError(genericSymbol)); 3608 } 3609 } 3610 set_inheritFromParent(false); 3611 } 3612 FindSymbol(name)->set(subpFlag); // PushScope() created symbol 3613 return *symbol; 3614 } 3615 3616 void SubprogramVisitor::PushBlockDataScope(const parser::Name &name) { 3617 if (auto *prev{FindSymbol(name)}) { 3618 if (prev->attrs().test(Attr::EXTERNAL) && prev->has<ProcEntityDetails>()) { 3619 if (prev->test(Symbol::Flag::Subroutine) || 3620 prev->test(Symbol::Flag::Function)) { 3621 Say2(name, "BLOCK DATA '%s' has been called"_err_en_US, *prev, 3622 "Previous call of '%s'"_en_US); 3623 } 3624 EraseSymbol(name); 3625 } 3626 } 3627 if (name.source.empty()) { 3628 // Don't let unnamed BLOCK DATA conflict with unnamed PROGRAM 3629 PushScope(Scope::Kind::BlockData, nullptr); 3630 } else { 3631 PushScope(Scope::Kind::BlockData, &MakeSymbol(name, SubprogramDetails{})); 3632 } 3633 } 3634 3635 // If name is a generic, return specific subprogram with the same name. 3636 Symbol *SubprogramVisitor::GetSpecificFromGeneric(const parser::Name &name) { 3637 if (auto *symbol{FindSymbol(name)}) { 3638 if (auto *details{symbol->detailsIf<GenericDetails>()}) { 3639 // found generic, want subprogram 3640 auto *specific{details->specific()}; 3641 if (!specific) { 3642 specific = 3643 &currScope().MakeSymbol(name.source, Attrs{}, SubprogramDetails{}); 3644 if (details->derivedType()) { 3645 // A specific procedure with the same name as a derived type 3646 SayAlreadyDeclared(name, *details->derivedType()); 3647 } else { 3648 details->set_specific(Resolve(name, *specific)); 3649 } 3650 } else if (isGeneric()) { 3651 SayAlreadyDeclared(name, *specific); 3652 } 3653 if (!specific->has<SubprogramDetails>()) { 3654 specific->set_details(SubprogramDetails{}); 3655 } 3656 return specific; 3657 } 3658 } 3659 return nullptr; 3660 } 3661 3662 // DeclarationVisitor implementation 3663 3664 bool DeclarationVisitor::BeginDecl() { 3665 BeginDeclTypeSpec(); 3666 BeginArraySpec(); 3667 return BeginAttrs(); 3668 } 3669 void DeclarationVisitor::EndDecl() { 3670 EndDeclTypeSpec(); 3671 EndArraySpec(); 3672 EndAttrs(); 3673 } 3674 3675 bool DeclarationVisitor::CheckUseError(const parser::Name &name) { 3676 const auto *details{ 3677 name.symbol ? name.symbol->detailsIf<UseErrorDetails>() : nullptr}; 3678 if (!details) { 3679 return false; 3680 } 3681 Message &msg{Say(name, "Reference to '%s' is ambiguous"_err_en_US)}; 3682 for (const auto &[location, module] : details->occurrences()) { 3683 msg.Attach(location, "'%s' was use-associated from module '%s'"_en_US, 3684 name.source, module->GetName().value()); 3685 } 3686 context().SetError(*name.symbol); 3687 return true; 3688 } 3689 3690 // Report error if accessibility of symbol doesn't match isPrivate. 3691 void DeclarationVisitor::CheckAccessibility( 3692 const SourceName &name, bool isPrivate, Symbol &symbol) { 3693 if (symbol.attrs().test(Attr::PRIVATE) != isPrivate) { 3694 Say2(name, 3695 "'%s' does not have the same accessibility as its previous declaration"_err_en_US, 3696 symbol, "Previous declaration of '%s'"_en_US); 3697 } 3698 } 3699 3700 void DeclarationVisitor::Post(const parser::TypeDeclarationStmt &) { 3701 if (!GetAttrs().HasAny({Attr::POINTER, Attr::ALLOCATABLE})) { // C702 3702 if (const auto *typeSpec{GetDeclTypeSpec()}) { 3703 if (typeSpec->category() == DeclTypeSpec::Character) { 3704 if (typeSpec->characterTypeSpec().length().isDeferred()) { 3705 Say("The type parameter LEN cannot be deferred without" 3706 " the POINTER or ALLOCATABLE attribute"_err_en_US); 3707 } 3708 } else if (const DerivedTypeSpec * derivedSpec{typeSpec->AsDerived()}) { 3709 for (const auto &pair : derivedSpec->parameters()) { 3710 if (pair.second.isDeferred()) { 3711 Say(currStmtSource().value(), 3712 "The value of type parameter '%s' cannot be deferred" 3713 " without the POINTER or ALLOCATABLE attribute"_err_en_US, 3714 pair.first); 3715 } 3716 } 3717 } 3718 } 3719 } 3720 EndDecl(); 3721 } 3722 3723 void DeclarationVisitor::Post(const parser::DimensionStmt::Declaration &x) { 3724 DeclareObjectEntity(std::get<parser::Name>(x.t)); 3725 } 3726 void DeclarationVisitor::Post(const parser::CodimensionDecl &x) { 3727 DeclareObjectEntity(std::get<parser::Name>(x.t)); 3728 } 3729 3730 bool DeclarationVisitor::Pre(const parser::Initialization &) { 3731 // Defer inspection of initializers to Initialization() so that the 3732 // symbol being initialized will be available within the initialization 3733 // expression. 3734 return false; 3735 } 3736 3737 void DeclarationVisitor::Post(const parser::EntityDecl &x) { 3738 const auto &name{std::get<parser::ObjectName>(x.t)}; 3739 Attrs attrs{attrs_ ? HandleSaveName(name.source, *attrs_) : Attrs{}}; 3740 Symbol &symbol{DeclareUnknownEntity(name, attrs)}; 3741 symbol.ReplaceName(name.source); 3742 if (const auto &init{std::get<std::optional<parser::Initialization>>(x.t)}) { 3743 if (ConvertToObjectEntity(symbol)) { 3744 Initialization(name, *init, false); 3745 } 3746 } else if (attrs.test(Attr::PARAMETER)) { // C882, C883 3747 Say(name, "Missing initialization for parameter '%s'"_err_en_US); 3748 } 3749 } 3750 3751 void DeclarationVisitor::Post(const parser::PointerDecl &x) { 3752 const auto &name{std::get<parser::Name>(x.t)}; 3753 if (const auto &deferredShapeSpecs{ 3754 std::get<std::optional<parser::DeferredShapeSpecList>>(x.t)}) { 3755 CHECK(arraySpec().empty()); 3756 BeginArraySpec(); 3757 set_arraySpec(AnalyzeDeferredShapeSpecList(context(), *deferredShapeSpecs)); 3758 Symbol &symbol{DeclareObjectEntity(name, Attrs{Attr::POINTER})}; 3759 symbol.ReplaceName(name.source); 3760 EndArraySpec(); 3761 } else { 3762 HandleAttributeStmt(Attr::POINTER, std::get<parser::Name>(x.t)); 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 common::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 common::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 common::visit(common::visitors{ 5833 [&](const Indirection<parser::Variable> &y) { 5834 Walk(y.value()); 5835 const parser::Name &first{ 5836 parser::GetFirstName(y.value())}; 5837 if (first.symbol) { 5838 first.symbol->set(Symbol::Flag::InDataStmt); 5839 } 5840 }, 5841 [&](const parser::DataImpliedDo &y) { 5842 PushScope(Scope::Kind::ImpliedDos, nullptr); 5843 Walk(y); 5844 PopScope(); 5845 }, 5846 }, 5847 x.u); 5848 return false; 5849 } 5850 5851 bool ConstructVisitor::Pre(const parser::DataStmtValue &x) { 5852 const auto &data{std::get<parser::DataStmtConstant>(x.t)}; 5853 auto &mutableData{const_cast<parser::DataStmtConstant &>(data)}; 5854 if (auto *elem{parser::Unwrap<parser::ArrayElement>(mutableData)}) { 5855 if (const auto *name{std::get_if<parser::Name>(&elem->base.u)}) { 5856 if (const Symbol * symbol{FindSymbol(*name)}) { 5857 const Symbol &ultimate{symbol->GetUltimate()}; 5858 if (ultimate.has<DerivedTypeDetails>()) { 5859 mutableData.u = elem->ConvertToStructureConstructor( 5860 DerivedTypeSpec{name->source, ultimate}); 5861 } 5862 } 5863 } 5864 } 5865 return true; 5866 } 5867 5868 bool ConstructVisitor::Pre(const parser::DoConstruct &x) { 5869 if (x.IsDoConcurrent()) { 5870 PushScope(Scope::Kind::Block, nullptr); 5871 } 5872 return true; 5873 } 5874 void ConstructVisitor::Post(const parser::DoConstruct &x) { 5875 if (x.IsDoConcurrent()) { 5876 PopScope(); 5877 } 5878 } 5879 5880 bool ConstructVisitor::Pre(const parser::ForallConstruct &) { 5881 PushScope(Scope::Kind::Forall, nullptr); 5882 return true; 5883 } 5884 void ConstructVisitor::Post(const parser::ForallConstruct &) { PopScope(); } 5885 bool ConstructVisitor::Pre(const parser::ForallStmt &) { 5886 PushScope(Scope::Kind::Forall, nullptr); 5887 return true; 5888 } 5889 void ConstructVisitor::Post(const parser::ForallStmt &) { PopScope(); } 5890 5891 bool ConstructVisitor::Pre(const parser::BlockStmt &x) { 5892 CheckDef(x.v); 5893 PushScope(Scope::Kind::Block, nullptr); 5894 return false; 5895 } 5896 bool ConstructVisitor::Pre(const parser::EndBlockStmt &x) { 5897 PopScope(); 5898 CheckRef(x.v); 5899 return false; 5900 } 5901 5902 void ConstructVisitor::Post(const parser::Selector &x) { 5903 GetCurrentAssociation().selector = ResolveSelector(x); 5904 } 5905 5906 void ConstructVisitor::Post(const parser::AssociateStmt &x) { 5907 CheckDef(x.t); 5908 PushScope(Scope::Kind::Block, nullptr); 5909 const auto assocCount{std::get<std::list<parser::Association>>(x.t).size()}; 5910 for (auto nthLastAssoc{assocCount}; nthLastAssoc > 0; --nthLastAssoc) { 5911 SetCurrentAssociation(nthLastAssoc); 5912 if (auto *symbol{MakeAssocEntity()}) { 5913 if (ExtractCoarrayRef(GetCurrentAssociation().selector.expr)) { // C1103 5914 Say("Selector must not be a coindexed object"_err_en_US); 5915 } 5916 SetTypeFromAssociation(*symbol); 5917 SetAttrsFromAssociation(*symbol); 5918 } 5919 } 5920 PopAssociation(assocCount); 5921 } 5922 5923 void ConstructVisitor::Post(const parser::EndAssociateStmt &x) { 5924 PopScope(); 5925 CheckRef(x.v); 5926 } 5927 5928 bool ConstructVisitor::Pre(const parser::Association &x) { 5929 PushAssociation(); 5930 const auto &name{std::get<parser::Name>(x.t)}; 5931 GetCurrentAssociation().name = &name; 5932 return true; 5933 } 5934 5935 bool ConstructVisitor::Pre(const parser::ChangeTeamStmt &x) { 5936 CheckDef(x.t); 5937 PushScope(Scope::Kind::Block, nullptr); 5938 PushAssociation(); 5939 return true; 5940 } 5941 5942 void ConstructVisitor::Post(const parser::CoarrayAssociation &x) { 5943 const auto &decl{std::get<parser::CodimensionDecl>(x.t)}; 5944 const auto &name{std::get<parser::Name>(decl.t)}; 5945 if (auto *symbol{FindInScope(name)}) { 5946 const auto &selector{std::get<parser::Selector>(x.t)}; 5947 if (auto sel{ResolveSelector(selector)}) { 5948 const Symbol *whole{UnwrapWholeSymbolDataRef(sel.expr)}; 5949 if (!whole || whole->Corank() == 0) { 5950 Say(sel.source, // C1116 5951 "Selector in coarray association must name a coarray"_err_en_US); 5952 } else if (auto dynType{sel.expr->GetType()}) { 5953 if (!symbol->GetType()) { 5954 symbol->SetType(ToDeclTypeSpec(std::move(*dynType))); 5955 } 5956 } 5957 } 5958 } 5959 } 5960 5961 void ConstructVisitor::Post(const parser::EndChangeTeamStmt &x) { 5962 PopAssociation(); 5963 PopScope(); 5964 CheckRef(x.t); 5965 } 5966 5967 bool ConstructVisitor::Pre(const parser::SelectTypeConstruct &) { 5968 PushAssociation(); 5969 return true; 5970 } 5971 5972 void ConstructVisitor::Post(const parser::SelectTypeConstruct &) { 5973 PopAssociation(); 5974 } 5975 5976 void ConstructVisitor::Post(const parser::SelectTypeStmt &x) { 5977 auto &association{GetCurrentAssociation()}; 5978 if (const std::optional<parser::Name> &name{std::get<1>(x.t)}) { 5979 // This isn't a name in the current scope, it is in each TypeGuardStmt 5980 MakePlaceholder(*name, MiscDetails::Kind::SelectTypeAssociateName); 5981 association.name = &*name; 5982 auto exprType{association.selector.expr->GetType()}; 5983 if (ExtractCoarrayRef(association.selector.expr)) { // C1103 5984 Say("Selector must not be a coindexed object"_err_en_US); 5985 } 5986 if (exprType && !exprType->IsPolymorphic()) { // C1159 5987 Say(association.selector.source, 5988 "Selector '%s' in SELECT TYPE statement must be " 5989 "polymorphic"_err_en_US); 5990 } 5991 } else { 5992 if (const Symbol * 5993 whole{UnwrapWholeSymbolDataRef(association.selector.expr)}) { 5994 ConvertToObjectEntity(const_cast<Symbol &>(*whole)); 5995 if (!IsVariableName(*whole)) { 5996 Say(association.selector.source, // C901 5997 "Selector is not a variable"_err_en_US); 5998 association = {}; 5999 } 6000 if (const DeclTypeSpec * type{whole->GetType()}) { 6001 if (!type->IsPolymorphic()) { // C1159 6002 Say(association.selector.source, 6003 "Selector '%s' in SELECT TYPE statement must be " 6004 "polymorphic"_err_en_US); 6005 } 6006 } 6007 } else { 6008 Say(association.selector.source, // C1157 6009 "Selector is not a named variable: 'associate-name =>' is required"_err_en_US); 6010 association = {}; 6011 } 6012 } 6013 } 6014 6015 void ConstructVisitor::Post(const parser::SelectRankStmt &x) { 6016 auto &association{GetCurrentAssociation()}; 6017 if (const std::optional<parser::Name> &name{std::get<1>(x.t)}) { 6018 // This isn't a name in the current scope, it is in each SelectRankCaseStmt 6019 MakePlaceholder(*name, MiscDetails::Kind::SelectRankAssociateName); 6020 association.name = &*name; 6021 } 6022 } 6023 6024 bool ConstructVisitor::Pre(const parser::SelectTypeConstruct::TypeCase &) { 6025 PushScope(Scope::Kind::Block, nullptr); 6026 return true; 6027 } 6028 void ConstructVisitor::Post(const parser::SelectTypeConstruct::TypeCase &) { 6029 PopScope(); 6030 } 6031 6032 bool ConstructVisitor::Pre(const parser::SelectRankConstruct::RankCase &) { 6033 PushScope(Scope::Kind::Block, nullptr); 6034 return true; 6035 } 6036 void ConstructVisitor::Post(const parser::SelectRankConstruct::RankCase &) { 6037 PopScope(); 6038 } 6039 6040 void ConstructVisitor::Post(const parser::TypeGuardStmt::Guard &x) { 6041 if (auto *symbol{MakeAssocEntity()}) { 6042 if (std::holds_alternative<parser::Default>(x.u)) { 6043 SetTypeFromAssociation(*symbol); 6044 } else if (const auto *type{GetDeclTypeSpec()}) { 6045 symbol->SetType(*type); 6046 } 6047 SetAttrsFromAssociation(*symbol); 6048 } 6049 } 6050 6051 void ConstructVisitor::Post(const parser::SelectRankCaseStmt::Rank &x) { 6052 if (auto *symbol{MakeAssocEntity()}) { 6053 SetTypeFromAssociation(*symbol); 6054 SetAttrsFromAssociation(*symbol); 6055 if (const auto *init{std::get_if<parser::ScalarIntConstantExpr>(&x.u)}) { 6056 if (auto val{EvaluateInt64(context(), *init)}) { 6057 auto &details{symbol->get<AssocEntityDetails>()}; 6058 details.set_rank(*val); 6059 } 6060 } 6061 } 6062 } 6063 6064 bool ConstructVisitor::Pre(const parser::SelectRankConstruct &) { 6065 PushAssociation(); 6066 return true; 6067 } 6068 6069 void ConstructVisitor::Post(const parser::SelectRankConstruct &) { 6070 PopAssociation(); 6071 } 6072 6073 bool ConstructVisitor::CheckDef(const std::optional<parser::Name> &x) { 6074 if (x) { 6075 MakeSymbol(*x, MiscDetails{MiscDetails::Kind::ConstructName}); 6076 } 6077 return true; 6078 } 6079 6080 void ConstructVisitor::CheckRef(const std::optional<parser::Name> &x) { 6081 if (x) { 6082 // Just add an occurrence of this name; checking is done in ValidateLabels 6083 FindSymbol(*x); 6084 } 6085 } 6086 6087 // Make a symbol for the associating entity of the current association. 6088 Symbol *ConstructVisitor::MakeAssocEntity() { 6089 Symbol *symbol{nullptr}; 6090 auto &association{GetCurrentAssociation()}; 6091 if (association.name) { 6092 symbol = &MakeSymbol(*association.name, UnknownDetails{}); 6093 if (symbol->has<AssocEntityDetails>() && symbol->owner() == currScope()) { 6094 Say(*association.name, // C1102 6095 "The associate name '%s' is already used in this associate statement"_err_en_US); 6096 return nullptr; 6097 } 6098 } else if (const Symbol * 6099 whole{UnwrapWholeSymbolDataRef(association.selector.expr)}) { 6100 symbol = &MakeSymbol(whole->name()); 6101 } else { 6102 return nullptr; 6103 } 6104 if (auto &expr{association.selector.expr}) { 6105 symbol->set_details(AssocEntityDetails{common::Clone(*expr)}); 6106 } else { 6107 symbol->set_details(AssocEntityDetails{}); 6108 } 6109 return symbol; 6110 } 6111 6112 // Set the type of symbol based on the current association selector. 6113 void ConstructVisitor::SetTypeFromAssociation(Symbol &symbol) { 6114 auto &details{symbol.get<AssocEntityDetails>()}; 6115 const MaybeExpr *pexpr{&details.expr()}; 6116 if (!*pexpr) { 6117 pexpr = &GetCurrentAssociation().selector.expr; 6118 } 6119 if (*pexpr) { 6120 const SomeExpr &expr{**pexpr}; 6121 if (std::optional<evaluate::DynamicType> type{expr.GetType()}) { 6122 if (const auto *charExpr{ 6123 evaluate::UnwrapExpr<evaluate::Expr<evaluate::SomeCharacter>>( 6124 expr)}) { 6125 symbol.SetType(ToDeclTypeSpec(std::move(*type), 6126 FoldExpr(common::visit( 6127 [](const auto &kindChar) { return kindChar.LEN(); }, 6128 charExpr->u)))); 6129 } else { 6130 symbol.SetType(ToDeclTypeSpec(std::move(*type))); 6131 } 6132 } else { 6133 // BOZ literals, procedure designators, &c. are not acceptable 6134 Say(symbol.name(), "Associate name '%s' must have a type"_err_en_US); 6135 } 6136 } 6137 } 6138 6139 // If current selector is a variable, set some of its attributes on symbol. 6140 void ConstructVisitor::SetAttrsFromAssociation(Symbol &symbol) { 6141 Attrs attrs{evaluate::GetAttrs(GetCurrentAssociation().selector.expr)}; 6142 symbol.attrs() |= attrs & 6143 Attrs{Attr::TARGET, Attr::ASYNCHRONOUS, Attr::VOLATILE, Attr::CONTIGUOUS}; 6144 if (attrs.test(Attr::POINTER)) { 6145 symbol.attrs().set(Attr::TARGET); 6146 } 6147 } 6148 6149 ConstructVisitor::Selector ConstructVisitor::ResolveSelector( 6150 const parser::Selector &x) { 6151 return common::visit(common::visitors{ 6152 [&](const parser::Expr &expr) { 6153 return Selector{expr.source, EvaluateExpr(x)}; 6154 }, 6155 [&](const parser::Variable &var) { 6156 return Selector{var.GetSource(), EvaluateExpr(x)}; 6157 }, 6158 }, 6159 x.u); 6160 } 6161 6162 // Set the current association to the nth to the last association on the 6163 // association stack. The top of the stack is at n = 1. This allows access 6164 // to the interior of a list of associations at the top of the stack. 6165 void ConstructVisitor::SetCurrentAssociation(std::size_t n) { 6166 CHECK(n > 0 && n <= associationStack_.size()); 6167 currentAssociation_ = &associationStack_[associationStack_.size() - n]; 6168 } 6169 6170 ConstructVisitor::Association &ConstructVisitor::GetCurrentAssociation() { 6171 CHECK(currentAssociation_); 6172 return *currentAssociation_; 6173 } 6174 6175 void ConstructVisitor::PushAssociation() { 6176 associationStack_.emplace_back(Association{}); 6177 currentAssociation_ = &associationStack_.back(); 6178 } 6179 6180 void ConstructVisitor::PopAssociation(std::size_t count) { 6181 CHECK(count > 0 && count <= associationStack_.size()); 6182 associationStack_.resize(associationStack_.size() - count); 6183 currentAssociation_ = 6184 associationStack_.empty() ? nullptr : &associationStack_.back(); 6185 } 6186 6187 const DeclTypeSpec &ConstructVisitor::ToDeclTypeSpec( 6188 evaluate::DynamicType &&type) { 6189 switch (type.category()) { 6190 SWITCH_COVERS_ALL_CASES 6191 case common::TypeCategory::Integer: 6192 case common::TypeCategory::Real: 6193 case common::TypeCategory::Complex: 6194 return context().MakeNumericType(type.category(), type.kind()); 6195 case common::TypeCategory::Logical: 6196 return context().MakeLogicalType(type.kind()); 6197 case common::TypeCategory::Derived: 6198 if (type.IsAssumedType()) { 6199 return currScope().MakeTypeStarType(); 6200 } else if (type.IsUnlimitedPolymorphic()) { 6201 return currScope().MakeClassStarType(); 6202 } else { 6203 return currScope().MakeDerivedType( 6204 type.IsPolymorphic() ? DeclTypeSpec::ClassDerived 6205 : DeclTypeSpec::TypeDerived, 6206 common::Clone(type.GetDerivedTypeSpec()) 6207 6208 ); 6209 } 6210 case common::TypeCategory::Character: 6211 CRASH_NO_CASE; 6212 } 6213 } 6214 6215 const DeclTypeSpec &ConstructVisitor::ToDeclTypeSpec( 6216 evaluate::DynamicType &&type, MaybeSubscriptIntExpr &&length) { 6217 CHECK(type.category() == common::TypeCategory::Character); 6218 if (length) { 6219 return currScope().MakeCharacterType( 6220 ParamValue{SomeIntExpr{*std::move(length)}, common::TypeParamAttr::Len}, 6221 KindExpr{type.kind()}); 6222 } else { 6223 return currScope().MakeCharacterType( 6224 ParamValue::Deferred(common::TypeParamAttr::Len), 6225 KindExpr{type.kind()}); 6226 } 6227 } 6228 6229 // ResolveNamesVisitor implementation 6230 6231 bool ResolveNamesVisitor::Pre(const parser::FunctionReference &x) { 6232 HandleCall(Symbol::Flag::Function, x.v); 6233 return false; 6234 } 6235 bool ResolveNamesVisitor::Pre(const parser::CallStmt &x) { 6236 HandleCall(Symbol::Flag::Subroutine, x.v); 6237 return false; 6238 } 6239 6240 bool ResolveNamesVisitor::Pre(const parser::ImportStmt &x) { 6241 auto &scope{currScope()}; 6242 // Check C896 and C899: where IMPORT statements are allowed 6243 switch (scope.kind()) { 6244 case Scope::Kind::Module: 6245 if (scope.IsModule()) { 6246 Say("IMPORT is not allowed in a module scoping unit"_err_en_US); 6247 return false; 6248 } else if (x.kind == common::ImportKind::None) { 6249 Say("IMPORT,NONE is not allowed in a submodule scoping unit"_err_en_US); 6250 return false; 6251 } 6252 break; 6253 case Scope::Kind::MainProgram: 6254 Say("IMPORT is not allowed in a main program scoping unit"_err_en_US); 6255 return false; 6256 case Scope::Kind::Subprogram: 6257 if (scope.parent().IsGlobal()) { 6258 Say("IMPORT is not allowed in an external subprogram scoping unit"_err_en_US); 6259 return false; 6260 } 6261 break; 6262 case Scope::Kind::BlockData: // C1415 (in part) 6263 Say("IMPORT is not allowed in a BLOCK DATA subprogram"_err_en_US); 6264 return false; 6265 default:; 6266 } 6267 if (auto error{scope.SetImportKind(x.kind)}) { 6268 Say(std::move(*error)); 6269 } 6270 for (auto &name : x.names) { 6271 if (FindSymbol(scope.parent(), name)) { 6272 scope.add_importName(name.source); 6273 } else { 6274 Say(name, "'%s' not found in host scope"_err_en_US); 6275 } 6276 } 6277 prevImportStmt_ = currStmtSource(); 6278 return false; 6279 } 6280 6281 const parser::Name *DeclarationVisitor::ResolveStructureComponent( 6282 const parser::StructureComponent &x) { 6283 return FindComponent(ResolveDataRef(x.base), x.component); 6284 } 6285 6286 const parser::Name *DeclarationVisitor::ResolveDesignator( 6287 const parser::Designator &x) { 6288 return common::visit( 6289 common::visitors{ 6290 [&](const parser::DataRef &x) { return ResolveDataRef(x); }, 6291 [&](const parser::Substring &x) { 6292 return ResolveDataRef(std::get<parser::DataRef>(x.t)); 6293 }, 6294 }, 6295 x.u); 6296 } 6297 6298 const parser::Name *DeclarationVisitor::ResolveDataRef( 6299 const parser::DataRef &x) { 6300 return common::visit( 6301 common::visitors{ 6302 [=](const parser::Name &y) { return ResolveName(y); }, 6303 [=](const Indirection<parser::StructureComponent> &y) { 6304 return ResolveStructureComponent(y.value()); 6305 }, 6306 [&](const Indirection<parser::ArrayElement> &y) { 6307 Walk(y.value().subscripts); 6308 const parser::Name *name{ResolveDataRef(y.value().base)}; 6309 if (name && name->symbol) { 6310 if (!IsProcedure(*name->symbol)) { 6311 ConvertToObjectEntity(*name->symbol); 6312 } else if (!context().HasError(*name->symbol)) { 6313 SayWithDecl(*name, *name->symbol, 6314 "Cannot reference function '%s' as data"_err_en_US); 6315 } 6316 } 6317 return name; 6318 }, 6319 [&](const Indirection<parser::CoindexedNamedObject> &y) { 6320 Walk(y.value().imageSelector); 6321 return ResolveDataRef(y.value().base); 6322 }, 6323 }, 6324 x.u); 6325 } 6326 6327 // If implicit types are allowed, ensure name is in the symbol table. 6328 // Otherwise, report an error if it hasn't been declared. 6329 const parser::Name *DeclarationVisitor::ResolveName(const parser::Name &name) { 6330 FindSymbol(name); 6331 if (CheckForHostAssociatedImplicit(name)) { 6332 NotePossibleBadForwardRef(name); 6333 return &name; 6334 } 6335 if (Symbol * symbol{name.symbol}) { 6336 if (CheckUseError(name)) { 6337 return nullptr; // reported an error 6338 } 6339 NotePossibleBadForwardRef(name); 6340 symbol->set(Symbol::Flag::ImplicitOrError, false); 6341 if (IsUplevelReference(*symbol)) { 6342 MakeHostAssocSymbol(name, *symbol); 6343 } else if (IsDummy(*symbol) || 6344 (!symbol->GetType() && FindCommonBlockContaining(*symbol))) { 6345 ConvertToObjectEntity(*symbol); 6346 ApplyImplicitRules(*symbol); 6347 } 6348 if (checkIndexUseInOwnBounds_ && 6349 *checkIndexUseInOwnBounds_ == name.source) { 6350 Say(name, 6351 "Implied DO index '%s' uses an object of the same name in its bounds expressions"_port_en_US, 6352 name.source); 6353 } 6354 return &name; 6355 } 6356 if (isImplicitNoneType()) { 6357 Say(name, "No explicit type declared for '%s'"_err_en_US); 6358 return nullptr; 6359 } 6360 // Create the symbol then ensure it is accessible 6361 if (checkIndexUseInOwnBounds_ && *checkIndexUseInOwnBounds_ == name.source) { 6362 Say(name, 6363 "Implied DO index '%s' uses itself in its own bounds expressions"_err_en_US, 6364 name.source); 6365 } 6366 MakeSymbol(InclusiveScope(), name.source, Attrs{}); 6367 auto *symbol{FindSymbol(name)}; 6368 if (!symbol) { 6369 Say(name, 6370 "'%s' from host scoping unit is not accessible due to IMPORT"_err_en_US); 6371 return nullptr; 6372 } 6373 ConvertToObjectEntity(*symbol); 6374 ApplyImplicitRules(*symbol); 6375 NotePossibleBadForwardRef(name); 6376 return &name; 6377 } 6378 6379 // A specification expression may refer to a symbol in the host procedure that 6380 // is implicitly typed. Because specification parts are processed before 6381 // execution parts, this may be the first time we see the symbol. It can't be a 6382 // local in the current scope (because it's in a specification expression) so 6383 // either it is implicitly declared in the host procedure or it is an error. 6384 // We create a symbol in the host assuming it is the former; if that proves to 6385 // be wrong we report an error later in CheckDeclarations(). 6386 bool DeclarationVisitor::CheckForHostAssociatedImplicit( 6387 const parser::Name &name) { 6388 if (inExecutionPart_) { 6389 return false; 6390 } 6391 if (name.symbol) { 6392 ApplyImplicitRules(*name.symbol, true); 6393 } 6394 Symbol *hostSymbol; 6395 Scope *host{GetHostProcedure()}; 6396 if (!host || isImplicitNoneType(*host)) { 6397 return false; 6398 } 6399 if (!name.symbol) { 6400 hostSymbol = &MakeSymbol(*host, name.source, Attrs{}); 6401 ConvertToObjectEntity(*hostSymbol); 6402 ApplyImplicitRules(*hostSymbol); 6403 hostSymbol->set(Symbol::Flag::ImplicitOrError); 6404 } else if (name.symbol->test(Symbol::Flag::ImplicitOrError)) { 6405 hostSymbol = name.symbol; 6406 } else { 6407 return false; 6408 } 6409 Symbol &symbol{MakeHostAssocSymbol(name, *hostSymbol)}; 6410 if (isImplicitNoneType()) { 6411 symbol.get<HostAssocDetails>().implicitOrExplicitTypeError = true; 6412 } else { 6413 symbol.get<HostAssocDetails>().implicitOrSpecExprError = true; 6414 } 6415 return true; 6416 } 6417 6418 bool DeclarationVisitor::IsUplevelReference(const Symbol &symbol) { 6419 const Scope &symbolUnit{GetProgramUnitContaining(symbol)}; 6420 if (symbolUnit == GetProgramUnitContaining(currScope())) { 6421 return false; 6422 } else { 6423 Scope::Kind kind{symbolUnit.kind()}; 6424 return kind == Scope::Kind::Subprogram || kind == Scope::Kind::MainProgram; 6425 } 6426 } 6427 6428 // base is a part-ref of a derived type; find the named component in its type. 6429 // Also handles intrinsic type parameter inquiries (%kind, %len) and 6430 // COMPLEX component references (%re, %im). 6431 const parser::Name *DeclarationVisitor::FindComponent( 6432 const parser::Name *base, const parser::Name &component) { 6433 if (!base || !base->symbol) { 6434 return nullptr; 6435 } 6436 if (auto *misc{base->symbol->detailsIf<MiscDetails>()}) { 6437 if (component.source == "kind") { 6438 if (misc->kind() == MiscDetails::Kind::ComplexPartRe || 6439 misc->kind() == MiscDetails::Kind::ComplexPartIm || 6440 misc->kind() == MiscDetails::Kind::KindParamInquiry || 6441 misc->kind() == MiscDetails::Kind::LenParamInquiry) { 6442 // x%{re,im,kind,len}%kind 6443 MakePlaceholder(component, MiscDetails::Kind::KindParamInquiry); 6444 return &component; 6445 } 6446 } 6447 } 6448 auto &symbol{base->symbol->GetUltimate()}; 6449 if (!symbol.has<AssocEntityDetails>() && !ConvertToObjectEntity(symbol)) { 6450 SayWithDecl(*base, symbol, 6451 "'%s' is an invalid base for a component reference"_err_en_US); 6452 return nullptr; 6453 } 6454 auto *type{symbol.GetType()}; 6455 if (!type) { 6456 return nullptr; // should have already reported error 6457 } 6458 if (const IntrinsicTypeSpec * intrinsic{type->AsIntrinsic()}) { 6459 auto category{intrinsic->category()}; 6460 MiscDetails::Kind miscKind{MiscDetails::Kind::None}; 6461 if (component.source == "kind") { 6462 miscKind = MiscDetails::Kind::KindParamInquiry; 6463 } else if (category == TypeCategory::Character) { 6464 if (component.source == "len") { 6465 miscKind = MiscDetails::Kind::LenParamInquiry; 6466 } 6467 } else if (category == TypeCategory::Complex) { 6468 if (component.source == "re") { 6469 miscKind = MiscDetails::Kind::ComplexPartRe; 6470 } else if (component.source == "im") { 6471 miscKind = MiscDetails::Kind::ComplexPartIm; 6472 } 6473 } 6474 if (miscKind != MiscDetails::Kind::None) { 6475 MakePlaceholder(component, miscKind); 6476 return &component; 6477 } 6478 } else if (const DerivedTypeSpec * derived{type->AsDerived()}) { 6479 if (const Scope * scope{derived->scope()}) { 6480 if (Resolve(component, scope->FindComponent(component.source))) { 6481 if (auto msg{ 6482 CheckAccessibleComponent(currScope(), *component.symbol)}) { 6483 context().Say(component.source, *msg); 6484 } 6485 return &component; 6486 } else { 6487 SayDerivedType(component.source, 6488 "Component '%s' not found in derived type '%s'"_err_en_US, *scope); 6489 } 6490 } 6491 return nullptr; 6492 } 6493 if (symbol.test(Symbol::Flag::Implicit)) { 6494 Say(*base, 6495 "'%s' is not an object of derived type; it is implicitly typed"_err_en_US); 6496 } else { 6497 SayWithDecl( 6498 *base, symbol, "'%s' is not an object of derived type"_err_en_US); 6499 } 6500 return nullptr; 6501 } 6502 6503 void DeclarationVisitor::Initialization(const parser::Name &name, 6504 const parser::Initialization &init, bool inComponentDecl) { 6505 // Traversal of the initializer was deferred to here so that the 6506 // symbol being declared can be available for use in the expression, e.g.: 6507 // real, parameter :: x = tiny(x) 6508 if (!name.symbol) { 6509 return; 6510 } 6511 Symbol &ultimate{name.symbol->GetUltimate()}; 6512 if (IsAllocatable(ultimate)) { 6513 Say(name, "Allocatable object '%s' cannot be initialized"_err_en_US); 6514 return; 6515 } 6516 if (auto *object{ultimate.detailsIf<ObjectEntityDetails>()}) { 6517 // TODO: check C762 - all bounds and type parameters of component 6518 // are colons or constant expressions if component is initialized 6519 common::visit( 6520 common::visitors{ 6521 [&](const parser::ConstantExpr &expr) { 6522 NonPointerInitialization(name, expr); 6523 }, 6524 [&](const parser::NullInit &null) { 6525 Walk(null); 6526 if (auto nullInit{EvaluateExpr(null)}) { 6527 if (!evaluate::IsNullPointer(*nullInit)) { 6528 Say(name, 6529 "Pointer initializer must be intrinsic NULL()"_err_en_US); // C813 6530 } else if (IsPointer(ultimate)) { 6531 object->set_init(std::move(*nullInit)); 6532 } else { 6533 Say(name, 6534 "Non-pointer component '%s' initialized with null pointer"_err_en_US); 6535 } 6536 } 6537 }, 6538 [&](const parser::InitialDataTarget &) { 6539 // Defer analysis to the end of the specification part 6540 // so that forward references and attribute checks like SAVE 6541 // work better. 6542 ultimate.set(Symbol::Flag::InDataStmt); 6543 }, 6544 [&](const std::list<Indirection<parser::DataStmtValue>> &) { 6545 // Handled later in data-to-inits conversion 6546 ultimate.set(Symbol::Flag::InDataStmt); 6547 }, 6548 }, 6549 init.u); 6550 } 6551 } 6552 6553 void DeclarationVisitor::PointerInitialization( 6554 const parser::Name &name, const parser::InitialDataTarget &target) { 6555 if (name.symbol) { 6556 Symbol &ultimate{name.symbol->GetUltimate()}; 6557 if (!context().HasError(ultimate)) { 6558 if (IsPointer(ultimate)) { 6559 if (auto *details{ultimate.detailsIf<ObjectEntityDetails>()}) { 6560 CHECK(!details->init()); 6561 Walk(target); 6562 if (MaybeExpr expr{EvaluateExpr(target)}) { 6563 // Validation is done in declaration checking. 6564 details->set_init(std::move(*expr)); 6565 } 6566 } 6567 } else { 6568 Say(name, 6569 "'%s' is not a pointer but is initialized like one"_err_en_US); 6570 context().SetError(ultimate); 6571 } 6572 } 6573 } 6574 } 6575 void DeclarationVisitor::PointerInitialization( 6576 const parser::Name &name, const parser::ProcPointerInit &target) { 6577 if (name.symbol) { 6578 Symbol &ultimate{name.symbol->GetUltimate()}; 6579 if (!context().HasError(ultimate)) { 6580 if (IsProcedurePointer(ultimate)) { 6581 auto &details{ultimate.get<ProcEntityDetails>()}; 6582 CHECK(!details.init()); 6583 Walk(target); 6584 if (const auto *targetName{std::get_if<parser::Name>(&target.u)}) { 6585 if (targetName->symbol) { 6586 // Validation is done in declaration checking. 6587 details.set_init(*targetName->symbol); 6588 } 6589 } else { 6590 details.set_init(nullptr); // explicit NULL() 6591 } 6592 } else { 6593 Say(name, 6594 "'%s' is not a procedure pointer but is initialized " 6595 "like one"_err_en_US); 6596 context().SetError(ultimate); 6597 } 6598 } 6599 } 6600 } 6601 6602 void DeclarationVisitor::NonPointerInitialization( 6603 const parser::Name &name, const parser::ConstantExpr &expr) { 6604 if (name.symbol) { 6605 Symbol &ultimate{name.symbol->GetUltimate()}; 6606 if (!context().HasError(ultimate) && !context().HasError(name.symbol)) { 6607 if (IsPointer(ultimate)) { 6608 Say(name, 6609 "'%s' is a pointer but is not initialized like one"_err_en_US); 6610 } else if (auto *details{ultimate.detailsIf<ObjectEntityDetails>()}) { 6611 CHECK(!details->init()); 6612 Walk(expr); 6613 if (ultimate.owner().IsParameterizedDerivedType()) { 6614 // Save the expression for per-instantiation analysis. 6615 details->set_unanalyzedPDTComponentInit(&expr.thing.value()); 6616 } else { 6617 if (MaybeExpr folded{EvaluateNonPointerInitializer( 6618 ultimate, expr, expr.thing.value().source)}) { 6619 details->set_init(std::move(*folded)); 6620 } 6621 } 6622 } 6623 } 6624 } 6625 } 6626 6627 void ResolveNamesVisitor::HandleCall( 6628 Symbol::Flag procFlag, const parser::Call &call) { 6629 common::visit( 6630 common::visitors{ 6631 [&](const parser::Name &x) { HandleProcedureName(procFlag, x); }, 6632 [&](const parser::ProcComponentRef &x) { Walk(x); }, 6633 }, 6634 std::get<parser::ProcedureDesignator>(call.t).u); 6635 Walk(std::get<std::list<parser::ActualArgSpec>>(call.t)); 6636 } 6637 6638 void ResolveNamesVisitor::HandleProcedureName( 6639 Symbol::Flag flag, const parser::Name &name) { 6640 CHECK(flag == Symbol::Flag::Function || flag == Symbol::Flag::Subroutine); 6641 auto *symbol{FindSymbol(NonDerivedTypeScope(), name)}; 6642 if (!symbol) { 6643 if (IsIntrinsic(name.source, flag)) { 6644 symbol = 6645 &MakeSymbol(InclusiveScope(), name.source, Attrs{Attr::INTRINSIC}); 6646 } else { 6647 symbol = &MakeSymbol(context().globalScope(), name.source, Attrs{}); 6648 } 6649 Resolve(name, *symbol); 6650 if (!symbol->attrs().test(Attr::INTRINSIC)) { 6651 if (CheckImplicitNoneExternal(name.source, *symbol)) { 6652 MakeExternal(*symbol); 6653 } 6654 } 6655 ConvertToProcEntity(*symbol); 6656 SetProcFlag(name, *symbol, flag); 6657 } else if (CheckUseError(name)) { 6658 // error was reported 6659 } else { 6660 auto &nonUltimateSymbol = *symbol; 6661 symbol = &Resolve(name, symbol)->GetUltimate(); 6662 bool convertedToProcEntity{ConvertToProcEntity(*symbol)}; 6663 if (convertedToProcEntity && !symbol->attrs().test(Attr::EXTERNAL) && 6664 IsIntrinsic(symbol->name(), flag) && !IsDummy(*symbol)) { 6665 AcquireIntrinsicProcedureFlags(*symbol); 6666 } 6667 if (!SetProcFlag(name, *symbol, flag)) { 6668 return; // reported error 6669 } 6670 if (!symbol->has<GenericDetails>()) { 6671 CheckImplicitNoneExternal(name.source, *symbol); 6672 } 6673 if (symbol->has<SubprogramDetails>() && 6674 symbol->attrs().test(Attr::ABSTRACT)) { 6675 Say(name, "Abstract interface '%s' may not be called"_err_en_US); 6676 } else if (IsProcedure(*symbol) || symbol->has<DerivedTypeDetails>() || 6677 symbol->has<AssocEntityDetails>()) { 6678 // Symbols with DerivedTypeDetails and AssocEntityDetails are accepted 6679 // here as procedure-designators because this means the related 6680 // FunctionReference are mis-parsed structure constructors or array 6681 // references that will be fixed later when analyzing expressions. 6682 } else if (symbol->has<ObjectEntityDetails>()) { 6683 // Symbols with ObjectEntityDetails are also accepted because this can be 6684 // a mis-parsed array references that will be fixed later. Ensure that if 6685 // this is a symbol from a host procedure, a symbol with HostAssocDetails 6686 // is created for the current scope. 6687 // Operate on non ultimate symbol so that HostAssocDetails are also 6688 // created for symbols used associated in the host procedure. 6689 if (IsUplevelReference(nonUltimateSymbol)) { 6690 MakeHostAssocSymbol(name, nonUltimateSymbol); 6691 } 6692 } else if (symbol->test(Symbol::Flag::Implicit)) { 6693 Say(name, 6694 "Use of '%s' as a procedure conflicts with its implicit definition"_err_en_US); 6695 } else { 6696 SayWithDecl(name, *symbol, 6697 "Use of '%s' as a procedure conflicts with its declaration"_err_en_US); 6698 } 6699 } 6700 } 6701 6702 bool ResolveNamesVisitor::CheckImplicitNoneExternal( 6703 const SourceName &name, const Symbol &symbol) { 6704 if (isImplicitNoneExternal() && !symbol.attrs().test(Attr::EXTERNAL) && 6705 !symbol.attrs().test(Attr::INTRINSIC) && !symbol.HasExplicitInterface()) { 6706 Say(name, 6707 "'%s' is an external procedure without the EXTERNAL" 6708 " attribute in a scope with IMPLICIT NONE(EXTERNAL)"_err_en_US); 6709 return false; 6710 } 6711 return true; 6712 } 6713 6714 // Variant of HandleProcedureName() for use while skimming the executable 6715 // part of a subprogram to catch calls to dummy procedures that are part 6716 // of the subprogram's interface, and to mark as procedures any symbols 6717 // that might otherwise have been miscategorized as objects. 6718 void ResolveNamesVisitor::NoteExecutablePartCall( 6719 Symbol::Flag flag, const parser::Call &call) { 6720 auto &designator{std::get<parser::ProcedureDesignator>(call.t)}; 6721 if (const auto *name{std::get_if<parser::Name>(&designator.u)}) { 6722 // Subtlety: The symbol pointers in the parse tree are not set, because 6723 // they might end up resolving elsewhere (e.g., construct entities in 6724 // SELECT TYPE). 6725 if (Symbol * symbol{currScope().FindSymbol(name->source)}) { 6726 Symbol::Flag other{flag == Symbol::Flag::Subroutine 6727 ? Symbol::Flag::Function 6728 : Symbol::Flag::Subroutine}; 6729 if (!symbol->test(other)) { 6730 ConvertToProcEntity(*symbol); 6731 if (symbol->has<ProcEntityDetails>()) { 6732 symbol->set(flag); 6733 if (IsDummy(*symbol)) { 6734 symbol->attrs().set(Attr::EXTERNAL); 6735 } 6736 ApplyImplicitRules(*symbol); 6737 } 6738 } 6739 } 6740 } 6741 } 6742 6743 static bool IsLocallyImplicitGlobalSymbol( 6744 const Symbol &symbol, const parser::Name &localName) { 6745 return symbol.owner().IsGlobal() && 6746 (!symbol.scope() || 6747 !symbol.scope()->sourceRange().Contains(localName.source)); 6748 } 6749 6750 static bool TypesMismatchIfNonNull( 6751 const DeclTypeSpec *type1, const DeclTypeSpec *type2) { 6752 return type1 && type2 && *type1 != *type2; 6753 } 6754 6755 // Check and set the Function or Subroutine flag on symbol; false on error. 6756 bool ResolveNamesVisitor::SetProcFlag( 6757 const parser::Name &name, Symbol &symbol, Symbol::Flag flag) { 6758 if (symbol.test(Symbol::Flag::Function) && flag == Symbol::Flag::Subroutine) { 6759 SayWithDecl( 6760 name, symbol, "Cannot call function '%s' like a subroutine"_err_en_US); 6761 return false; 6762 } else if (symbol.test(Symbol::Flag::Subroutine) && 6763 flag == Symbol::Flag::Function) { 6764 SayWithDecl( 6765 name, symbol, "Cannot call subroutine '%s' like a function"_err_en_US); 6766 return false; 6767 } else if (flag == Symbol::Flag::Function && 6768 IsLocallyImplicitGlobalSymbol(symbol, name) && 6769 TypesMismatchIfNonNull(symbol.GetType(), GetImplicitType(symbol))) { 6770 SayWithDecl(name, symbol, 6771 "Implicit declaration of function '%s' has a different result type than in previous declaration"_err_en_US); 6772 return false; 6773 } else if (symbol.has<ProcEntityDetails>()) { 6774 symbol.set(flag); // in case it hasn't been set yet 6775 if (flag == Symbol::Flag::Function) { 6776 ApplyImplicitRules(symbol); 6777 } 6778 if (symbol.attrs().test(Attr::INTRINSIC)) { 6779 AcquireIntrinsicProcedureFlags(symbol); 6780 } 6781 } else if (symbol.GetType() && flag == Symbol::Flag::Subroutine) { 6782 SayWithDecl( 6783 name, symbol, "Cannot call function '%s' like a subroutine"_err_en_US); 6784 } else if (symbol.attrs().test(Attr::INTRINSIC)) { 6785 AcquireIntrinsicProcedureFlags(symbol); 6786 } 6787 return true; 6788 } 6789 6790 bool ModuleVisitor::Pre(const parser::AccessStmt &x) { 6791 Attr accessAttr{AccessSpecToAttr(std::get<parser::AccessSpec>(x.t))}; 6792 if (!currScope().IsModule()) { // C869 6793 Say(currStmtSource().value(), 6794 "%s statement may only appear in the specification part of a module"_err_en_US, 6795 EnumToString(accessAttr)); 6796 return false; 6797 } 6798 const auto &accessIds{std::get<std::list<parser::AccessId>>(x.t)}; 6799 if (accessIds.empty()) { 6800 if (prevAccessStmt_) { // C869 6801 Say("The default accessibility of this module has already been declared"_err_en_US) 6802 .Attach(*prevAccessStmt_, "Previous declaration"_en_US); 6803 } 6804 prevAccessStmt_ = currStmtSource(); 6805 defaultAccess_ = accessAttr; 6806 } else { 6807 for (const auto &accessId : accessIds) { 6808 common::visit( 6809 common::visitors{ 6810 [=](const parser::Name &y) { 6811 Resolve(y, SetAccess(y.source, accessAttr)); 6812 }, 6813 [=](const Indirection<parser::GenericSpec> &y) { 6814 auto info{GenericSpecInfo{y.value()}}; 6815 const auto &symbolName{info.symbolName()}; 6816 if (auto *symbol{FindInScope(symbolName)}) { 6817 info.Resolve(&SetAccess(symbolName, accessAttr, symbol)); 6818 } else if (info.kind().IsName()) { 6819 info.Resolve(&SetAccess(symbolName, accessAttr)); 6820 } else { 6821 Say(symbolName, "Generic spec '%s' not found"_err_en_US); 6822 } 6823 }, 6824 }, 6825 accessId.u); 6826 } 6827 } 6828 return false; 6829 } 6830 6831 // Set the access specification for this symbol. 6832 Symbol &ModuleVisitor::SetAccess( 6833 const SourceName &name, Attr attr, Symbol *symbol) { 6834 if (!symbol) { 6835 symbol = &MakeSymbol(name); 6836 } 6837 Attrs &attrs{symbol->attrs()}; 6838 if (attrs.HasAny({Attr::PUBLIC, Attr::PRIVATE})) { 6839 // PUBLIC/PRIVATE already set: make it a fatal error if it changed 6840 Attr prev = attrs.test(Attr::PUBLIC) ? Attr::PUBLIC : Attr::PRIVATE; 6841 Say(name, 6842 WithSeverity( 6843 "The accessibility of '%s' has already been specified as %s"_warn_en_US, 6844 attr != prev ? parser::Severity::Error : parser::Severity::Warning), 6845 MakeOpName(name), EnumToString(prev)); 6846 } else { 6847 attrs.set(attr); 6848 } 6849 return *symbol; 6850 } 6851 6852 static bool NeedsExplicitType(const Symbol &symbol) { 6853 if (symbol.has<UnknownDetails>()) { 6854 return true; 6855 } else if (const auto *details{symbol.detailsIf<EntityDetails>()}) { 6856 return !details->type(); 6857 } else if (const auto *details{symbol.detailsIf<ObjectEntityDetails>()}) { 6858 return !details->type(); 6859 } else if (const auto *details{symbol.detailsIf<ProcEntityDetails>()}) { 6860 return !details->interface().symbol() && !details->interface().type(); 6861 } else { 6862 return false; 6863 } 6864 } 6865 6866 bool ResolveNamesVisitor::Pre(const parser::SpecificationPart &x) { 6867 const auto &[accDecls, ompDecls, compilerDirectives, useStmts, importStmts, 6868 implicitPart, decls] = x.t; 6869 auto flagRestorer{common::ScopedSet(inSpecificationPart_, true)}; 6870 auto stateRestorer{ 6871 common::ScopedSet(specPartState_, SpecificationPartState{})}; 6872 Walk(accDecls); 6873 Walk(ompDecls); 6874 Walk(compilerDirectives); 6875 Walk(useStmts); 6876 ClearUseRenames(); 6877 ClearUseOnly(); 6878 ClearExplicitIntrinsicUses(); 6879 Walk(importStmts); 6880 Walk(implicitPart); 6881 for (const auto &decl : decls) { 6882 if (const auto *spec{ 6883 std::get_if<parser::SpecificationConstruct>(&decl.u)}) { 6884 PreSpecificationConstruct(*spec); 6885 } 6886 } 6887 Walk(decls); 6888 FinishSpecificationPart(decls); 6889 return false; 6890 } 6891 6892 // Initial processing on specification constructs, before visiting them. 6893 void ResolveNamesVisitor::PreSpecificationConstruct( 6894 const parser::SpecificationConstruct &spec) { 6895 common::visit( 6896 common::visitors{ 6897 [&](const parser::Statement<Indirection<parser::GenericStmt>> &y) { 6898 CreateGeneric(std::get<parser::GenericSpec>(y.statement.value().t)); 6899 }, 6900 [&](const Indirection<parser::InterfaceBlock> &y) { 6901 const auto &stmt{std::get<parser::Statement<parser::InterfaceStmt>>( 6902 y.value().t)}; 6903 if (const auto *spec{parser::Unwrap<parser::GenericSpec>(stmt)}) { 6904 CreateGeneric(*spec); 6905 } 6906 }, 6907 [&](const parser::Statement<parser::OtherSpecificationStmt> &y) { 6908 if (const auto *commonStmt{parser::Unwrap<parser::CommonStmt>(y)}) { 6909 CreateCommonBlockSymbols(*commonStmt); 6910 } 6911 }, 6912 [&](const auto &) {}, 6913 }, 6914 spec.u); 6915 } 6916 6917 void ResolveNamesVisitor::CreateCommonBlockSymbols( 6918 const parser::CommonStmt &commonStmt) { 6919 for (const parser::CommonStmt::Block &block : commonStmt.blocks) { 6920 const auto &[name, objects] = block.t; 6921 Symbol &commonBlock{MakeCommonBlockSymbol(name)}; 6922 for (const auto &object : objects) { 6923 Symbol &obj{DeclareObjectEntity(std::get<parser::Name>(object.t))}; 6924 if (auto *details{obj.detailsIf<ObjectEntityDetails>()}) { 6925 details->set_commonBlock(commonBlock); 6926 commonBlock.get<CommonBlockDetails>().add_object(obj); 6927 } 6928 } 6929 } 6930 } 6931 6932 void ResolveNamesVisitor::CreateGeneric(const parser::GenericSpec &x) { 6933 auto info{GenericSpecInfo{x}}; 6934 SourceName symbolName{info.symbolName()}; 6935 if (IsLogicalConstant(context(), symbolName)) { 6936 Say(symbolName, 6937 "Logical constant '%s' may not be used as a defined operator"_err_en_US); 6938 return; 6939 } 6940 GenericDetails genericDetails; 6941 Symbol *existing{nullptr}; 6942 // Check all variants of names, e.g. "operator(.ne.)" for "operator(/=)" 6943 for (const std::string &n : GetAllNames(context(), symbolName)) { 6944 existing = currScope().FindSymbol(n); 6945 if (existing) { 6946 break; 6947 } 6948 } 6949 if (existing) { 6950 Symbol &ultimate{existing->GetUltimate()}; 6951 if (const auto *existingGeneric{ultimate.detailsIf<GenericDetails>()}) { 6952 if (&ultimate.owner() != &currScope()) { 6953 // Create a local copy of a host or use associated generic so that 6954 // it can be locally extended without corrupting the original. 6955 genericDetails.CopyFrom(*existingGeneric); 6956 if (const auto *use{existing->detailsIf<UseDetails>()}) { 6957 AddGenericUse(genericDetails, existing->name(), use->symbol()); 6958 EraseSymbol(*existing); 6959 } 6960 existing = &MakeSymbol(symbolName, Attrs{}, std::move(genericDetails)); 6961 } 6962 info.Resolve(existing); 6963 return; 6964 } 6965 if (&existing->owner() == &currScope()) { 6966 if (ultimate.has<SubprogramDetails>() || 6967 ultimate.has<SubprogramNameDetails>()) { 6968 genericDetails.set_specific(ultimate); 6969 } else if (ultimate.has<DerivedTypeDetails>()) { 6970 genericDetails.set_derivedType(ultimate); 6971 } else { 6972 SayAlreadyDeclared(symbolName, *existing); 6973 return; 6974 } 6975 EraseSymbol(*existing); 6976 } 6977 } 6978 info.Resolve(&MakeSymbol(symbolName, Attrs{}, std::move(genericDetails))); 6979 } 6980 6981 void ResolveNamesVisitor::FinishSpecificationPart( 6982 const std::list<parser::DeclarationConstruct> &decls) { 6983 badStmtFuncFound_ = false; 6984 funcResultStack().CompleteFunctionResultType(); 6985 CheckImports(); 6986 bool inModule{currScope().kind() == Scope::Kind::Module}; 6987 for (auto &pair : currScope()) { 6988 auto &symbol{*pair.second}; 6989 if (NeedsExplicitType(symbol)) { 6990 ApplyImplicitRules(symbol); 6991 } 6992 if (IsDummy(symbol) && isImplicitNoneType() && 6993 symbol.test(Symbol::Flag::Implicit) && !context().HasError(symbol)) { 6994 Say(symbol.name(), 6995 "No explicit type declared for dummy argument '%s'"_err_en_US); 6996 context().SetError(symbol); 6997 } 6998 if (symbol.has<GenericDetails>()) { 6999 CheckGenericProcedures(symbol); 7000 } 7001 if (inModule && symbol.attrs().test(Attr::EXTERNAL) && 7002 !symbol.test(Symbol::Flag::Function) && 7003 !symbol.test(Symbol::Flag::Subroutine)) { 7004 // in a module, external proc without return type is subroutine 7005 symbol.set( 7006 symbol.GetType() ? Symbol::Flag::Function : Symbol::Flag::Subroutine); 7007 } 7008 if (!symbol.has<HostAssocDetails>()) { 7009 CheckPossibleBadForwardRef(symbol); 7010 } 7011 } 7012 currScope().InstantiateDerivedTypes(); 7013 for (const auto &decl : decls) { 7014 if (const auto *statement{std::get_if< 7015 parser::Statement<common::Indirection<parser::StmtFunctionStmt>>>( 7016 &decl.u)}) { 7017 AnalyzeStmtFunctionStmt(statement->statement.value()); 7018 } 7019 } 7020 // TODO: what about instantiations in BLOCK? 7021 CheckSaveStmts(); 7022 CheckCommonBlocks(); 7023 if (!inInterfaceBlock()) { 7024 // TODO: warn for the case where the EQUIVALENCE statement is in a 7025 // procedure declaration in an interface block 7026 CheckEquivalenceSets(); 7027 } 7028 } 7029 7030 // Analyze the bodies of statement functions now that the symbols in this 7031 // specification part have been fully declared and implicitly typed. 7032 void ResolveNamesVisitor::AnalyzeStmtFunctionStmt( 7033 const parser::StmtFunctionStmt &stmtFunc) { 7034 Symbol *symbol{std::get<parser::Name>(stmtFunc.t).symbol}; 7035 if (!symbol || !symbol->has<SubprogramDetails>()) { 7036 return; 7037 } 7038 auto &details{symbol->get<SubprogramDetails>()}; 7039 auto expr{AnalyzeExpr( 7040 context(), std::get<parser::Scalar<parser::Expr>>(stmtFunc.t))}; 7041 if (!expr) { 7042 context().SetError(*symbol); 7043 return; 7044 } 7045 if (auto type{evaluate::DynamicType::From(*symbol)}) { 7046 auto converted{ConvertToType(*type, std::move(*expr))}; 7047 if (!converted) { 7048 context().SetError(*symbol); 7049 return; 7050 } 7051 details.set_stmtFunction(std::move(*converted)); 7052 } else { 7053 details.set_stmtFunction(std::move(*expr)); 7054 } 7055 } 7056 7057 void ResolveNamesVisitor::CheckImports() { 7058 auto &scope{currScope()}; 7059 switch (scope.GetImportKind()) { 7060 case common::ImportKind::None: 7061 break; 7062 case common::ImportKind::All: 7063 // C8102: all entities in host must not be hidden 7064 for (const auto &pair : scope.parent()) { 7065 auto &name{pair.first}; 7066 std::optional<SourceName> scopeName{scope.GetName()}; 7067 if (!scopeName || name != *scopeName) { 7068 CheckImport(prevImportStmt_.value(), name); 7069 } 7070 } 7071 break; 7072 case common::ImportKind::Default: 7073 case common::ImportKind::Only: 7074 // C8102: entities named in IMPORT must not be hidden 7075 for (auto &name : scope.importNames()) { 7076 CheckImport(name, name); 7077 } 7078 break; 7079 } 7080 } 7081 7082 void ResolveNamesVisitor::CheckImport( 7083 const SourceName &location, const SourceName &name) { 7084 if (auto *symbol{FindInScope(name)}) { 7085 const Symbol &ultimate{symbol->GetUltimate()}; 7086 if (&ultimate.owner() == &currScope()) { 7087 Say(location, "'%s' from host is not accessible"_err_en_US, name) 7088 .Attach(symbol->name(), "'%s' is hidden by this entity"_en_US, 7089 symbol->name()); 7090 } 7091 } 7092 } 7093 7094 bool ResolveNamesVisitor::Pre(const parser::ImplicitStmt &x) { 7095 return CheckNotInBlock("IMPLICIT") && // C1107 7096 ImplicitRulesVisitor::Pre(x); 7097 } 7098 7099 void ResolveNamesVisitor::Post(const parser::PointerObject &x) { 7100 common::visit(common::visitors{ 7101 [&](const parser::Name &x) { ResolveName(x); }, 7102 [&](const parser::StructureComponent &x) { 7103 ResolveStructureComponent(x); 7104 }, 7105 }, 7106 x.u); 7107 } 7108 void ResolveNamesVisitor::Post(const parser::AllocateObject &x) { 7109 common::visit(common::visitors{ 7110 [&](const parser::Name &x) { ResolveName(x); }, 7111 [&](const parser::StructureComponent &x) { 7112 ResolveStructureComponent(x); 7113 }, 7114 }, 7115 x.u); 7116 } 7117 7118 bool ResolveNamesVisitor::Pre(const parser::PointerAssignmentStmt &x) { 7119 const auto &dataRef{std::get<parser::DataRef>(x.t)}; 7120 const auto &bounds{std::get<parser::PointerAssignmentStmt::Bounds>(x.t)}; 7121 const auto &expr{std::get<parser::Expr>(x.t)}; 7122 ResolveDataRef(dataRef); 7123 Walk(bounds); 7124 // Resolve unrestricted specific intrinsic procedures as in "p => cos". 7125 if (const parser::Name * name{parser::Unwrap<parser::Name>(expr)}) { 7126 if (NameIsKnownOrIntrinsic(*name)) { 7127 // If the name is known because it is an object entity from a host 7128 // procedure, create a host associated symbol. 7129 if (Symbol * symbol{name->symbol}; symbol && 7130 symbol->GetUltimate().has<ObjectEntityDetails>() && 7131 IsUplevelReference(*symbol)) { 7132 MakeHostAssocSymbol(*name, *symbol); 7133 } 7134 return false; 7135 } 7136 } 7137 Walk(expr); 7138 return false; 7139 } 7140 void ResolveNamesVisitor::Post(const parser::Designator &x) { 7141 ResolveDesignator(x); 7142 } 7143 7144 void ResolveNamesVisitor::Post(const parser::ProcComponentRef &x) { 7145 ResolveStructureComponent(x.v.thing); 7146 } 7147 void ResolveNamesVisitor::Post(const parser::TypeGuardStmt &x) { 7148 DeclTypeSpecVisitor::Post(x); 7149 ConstructVisitor::Post(x); 7150 } 7151 bool ResolveNamesVisitor::Pre(const parser::StmtFunctionStmt &x) { 7152 CheckNotInBlock("STATEMENT FUNCTION"); // C1107 7153 if (HandleStmtFunction(x)) { 7154 return false; 7155 } else { 7156 // This is an array element assignment: resolve names of indices 7157 const auto &names{std::get<std::list<parser::Name>>(x.t)}; 7158 for (auto &name : names) { 7159 ResolveName(name); 7160 } 7161 return true; 7162 } 7163 } 7164 7165 bool ResolveNamesVisitor::Pre(const parser::DefinedOpName &x) { 7166 const parser::Name &name{x.v}; 7167 if (FindSymbol(name)) { 7168 // OK 7169 } else if (IsLogicalConstant(context(), name.source)) { 7170 Say(name, 7171 "Logical constant '%s' may not be used as a defined operator"_err_en_US); 7172 } else { 7173 // Resolved later in expression semantics 7174 MakePlaceholder(name, MiscDetails::Kind::TypeBoundDefinedOp); 7175 } 7176 return false; 7177 } 7178 7179 void ResolveNamesVisitor::Post(const parser::AssignStmt &x) { 7180 if (auto *name{ResolveName(std::get<parser::Name>(x.t))}) { 7181 ConvertToObjectEntity(DEREF(name->symbol)); 7182 } 7183 } 7184 void ResolveNamesVisitor::Post(const parser::AssignedGotoStmt &x) { 7185 if (auto *name{ResolveName(std::get<parser::Name>(x.t))}) { 7186 ConvertToObjectEntity(DEREF(name->symbol)); 7187 } 7188 } 7189 7190 bool ResolveNamesVisitor::Pre(const parser::ProgramUnit &x) { 7191 if (std::holds_alternative<common::Indirection<parser::CompilerDirective>>( 7192 x.u)) { 7193 // TODO: global directives 7194 return true; 7195 } 7196 auto root{ProgramTree::Build(x)}; 7197 SetScope(topScope_); 7198 ResolveSpecificationParts(root); 7199 FinishSpecificationParts(root); 7200 inExecutionPart_ = true; 7201 ResolveExecutionParts(root); 7202 inExecutionPart_ = false; 7203 ResolveAccParts(context(), x); 7204 ResolveOmpParts(context(), x); 7205 return false; 7206 } 7207 7208 // References to procedures need to record that their symbols are known 7209 // to be procedures, so that they don't get converted to objects by default. 7210 class ExecutionPartSkimmer { 7211 public: 7212 explicit ExecutionPartSkimmer(ResolveNamesVisitor &resolver) 7213 : resolver_{resolver} {} 7214 7215 void Walk(const parser::ExecutionPart *exec) { 7216 if (exec) { 7217 parser::Walk(*exec, *this); 7218 } 7219 } 7220 7221 template <typename A> bool Pre(const A &) { return true; } 7222 template <typename A> void Post(const A &) {} 7223 void Post(const parser::FunctionReference &fr) { 7224 resolver_.NoteExecutablePartCall(Symbol::Flag::Function, fr.v); 7225 } 7226 void Post(const parser::CallStmt &cs) { 7227 resolver_.NoteExecutablePartCall(Symbol::Flag::Subroutine, cs.v); 7228 } 7229 7230 private: 7231 ResolveNamesVisitor &resolver_; 7232 }; 7233 7234 // Build the scope tree and resolve names in the specification parts of this 7235 // node and its children 7236 void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) { 7237 if (node.isSpecificationPartResolved()) { 7238 return; // been here already 7239 } 7240 node.set_isSpecificationPartResolved(); 7241 if (!BeginScopeForNode(node)) { 7242 return; // an error prevented scope from being created 7243 } 7244 Scope &scope{currScope()}; 7245 node.set_scope(scope); 7246 AddSubpNames(node); 7247 common::visit( 7248 [&](const auto *x) { 7249 if (x) { 7250 Walk(*x); 7251 } 7252 }, 7253 node.stmt()); 7254 Walk(node.spec()); 7255 // If this is a function, convert result to an object. This is to prevent the 7256 // result from being converted later to a function symbol if it is called 7257 // inside the function. 7258 // If the result is function pointer, then ConvertToObjectEntity will not 7259 // convert the result to an object, and calling the symbol inside the function 7260 // will result in calls to the result pointer. 7261 // A function cannot be called recursively if RESULT was not used to define a 7262 // distinct result name (15.6.2.2 point 4.). 7263 if (Symbol * symbol{scope.symbol()}) { 7264 if (auto *details{symbol->detailsIf<SubprogramDetails>()}) { 7265 if (details->isFunction()) { 7266 ConvertToObjectEntity(const_cast<Symbol &>(details->result())); 7267 } 7268 } 7269 } 7270 if (node.IsModule()) { 7271 ApplyDefaultAccess(); 7272 } 7273 for (auto &child : node.children()) { 7274 ResolveSpecificationParts(child); 7275 } 7276 ExecutionPartSkimmer{*this}.Walk(node.exec()); 7277 EndScopeForNode(node); 7278 // Ensure that every object entity has a type. 7279 for (auto &pair : *node.scope()) { 7280 ApplyImplicitRules(*pair.second); 7281 } 7282 } 7283 7284 // Add SubprogramNameDetails symbols for module and internal subprograms and 7285 // their ENTRY statements. 7286 void ResolveNamesVisitor::AddSubpNames(ProgramTree &node) { 7287 auto kind{ 7288 node.IsModule() ? SubprogramKind::Module : SubprogramKind::Internal}; 7289 for (auto &child : node.children()) { 7290 auto &symbol{MakeSymbol(child.name(), SubprogramNameDetails{kind, child})}; 7291 auto childKind{child.GetKind()}; 7292 if (childKind == ProgramTree::Kind::Function) { 7293 symbol.set(Symbol::Flag::Function); 7294 } else if (childKind == ProgramTree::Kind::Subroutine) { 7295 symbol.set(Symbol::Flag::Subroutine); 7296 } 7297 for (const auto &entryStmt : child.entryStmts()) { 7298 SubprogramNameDetails details{kind, child}; 7299 details.set_isEntryStmt(); 7300 auto &symbol{ 7301 MakeSymbol(std::get<parser::Name>(entryStmt->t), std::move(details))}; 7302 symbol.set(child.GetSubpFlag()); 7303 } 7304 } 7305 for (const auto &generic : node.genericSpecs()) { 7306 if (const auto *name{std::get_if<parser::Name>(&generic->u)}) { 7307 if (currScope().find(name->source) != currScope().end()) { 7308 // If this scope has both a generic interface and a contained 7309 // subprogram with the same name, create the generic's symbol 7310 // now so that any other generics of the same name that are pulled 7311 // into scope later via USE association will properly merge instead 7312 // of raising a bogus error due a conflict with the subprogram. 7313 CreateGeneric(*generic); 7314 } 7315 } 7316 } 7317 } 7318 7319 // Push a new scope for this node or return false on error. 7320 bool ResolveNamesVisitor::BeginScopeForNode(const ProgramTree &node) { 7321 switch (node.GetKind()) { 7322 SWITCH_COVERS_ALL_CASES 7323 case ProgramTree::Kind::Program: 7324 PushScope(Scope::Kind::MainProgram, 7325 &MakeSymbol(node.name(), MainProgramDetails{})); 7326 return true; 7327 case ProgramTree::Kind::Function: 7328 case ProgramTree::Kind::Subroutine: 7329 return BeginSubprogram( 7330 node.name(), node.GetSubpFlag(), node.HasModulePrefix()); 7331 case ProgramTree::Kind::MpSubprogram: 7332 return BeginMpSubprogram(node.name()); 7333 case ProgramTree::Kind::Module: 7334 BeginModule(node.name(), false); 7335 return true; 7336 case ProgramTree::Kind::Submodule: 7337 return BeginSubmodule(node.name(), node.GetParentId()); 7338 case ProgramTree::Kind::BlockData: 7339 PushBlockDataScope(node.name()); 7340 return true; 7341 } 7342 } 7343 7344 void ResolveNamesVisitor::EndScopeForNode(const ProgramTree &node) { 7345 EndSubprogram(); 7346 } 7347 7348 // Some analyses and checks, such as the processing of initializers of 7349 // pointers, are deferred until all of the pertinent specification parts 7350 // have been visited. This deferred processing enables the use of forward 7351 // references in these circumstances. 7352 class DeferredCheckVisitor { 7353 public: 7354 explicit DeferredCheckVisitor(ResolveNamesVisitor &resolver) 7355 : resolver_{resolver} {} 7356 7357 template <typename A> void Walk(const A &x) { parser::Walk(x, *this); } 7358 7359 template <typename A> bool Pre(const A &) { return true; } 7360 template <typename A> void Post(const A &) {} 7361 7362 void Post(const parser::DerivedTypeStmt &x) { 7363 const auto &name{std::get<parser::Name>(x.t)}; 7364 if (Symbol * symbol{name.symbol}) { 7365 if (Scope * scope{symbol->scope()}) { 7366 if (scope->IsDerivedType()) { 7367 resolver_.PushScope(*scope); 7368 pushedScope_ = true; 7369 } 7370 } 7371 } 7372 } 7373 void Post(const parser::EndTypeStmt &) { 7374 if (pushedScope_) { 7375 resolver_.PopScope(); 7376 pushedScope_ = false; 7377 } 7378 } 7379 7380 void Post(const parser::ProcInterface &pi) { 7381 if (const auto *name{std::get_if<parser::Name>(&pi.u)}) { 7382 resolver_.CheckExplicitInterface(*name); 7383 } 7384 } 7385 bool Pre(const parser::EntityDecl &decl) { 7386 Init(std::get<parser::Name>(decl.t), 7387 std::get<std::optional<parser::Initialization>>(decl.t)); 7388 return false; 7389 } 7390 bool Pre(const parser::ComponentDecl &decl) { 7391 Init(std::get<parser::Name>(decl.t), 7392 std::get<std::optional<parser::Initialization>>(decl.t)); 7393 return false; 7394 } 7395 bool Pre(const parser::ProcDecl &decl) { 7396 if (const auto &init{ 7397 std::get<std::optional<parser::ProcPointerInit>>(decl.t)}) { 7398 resolver_.PointerInitialization(std::get<parser::Name>(decl.t), *init); 7399 } 7400 return false; 7401 } 7402 void Post(const parser::TypeBoundProcedureStmt::WithInterface &tbps) { 7403 resolver_.CheckExplicitInterface(tbps.interfaceName); 7404 } 7405 void Post(const parser::TypeBoundProcedureStmt::WithoutInterface &tbps) { 7406 if (pushedScope_) { 7407 resolver_.CheckBindings(tbps); 7408 } 7409 } 7410 7411 private: 7412 void Init(const parser::Name &name, 7413 const std::optional<parser::Initialization> &init) { 7414 if (init) { 7415 if (const auto *target{ 7416 std::get_if<parser::InitialDataTarget>(&init->u)}) { 7417 resolver_.PointerInitialization(name, *target); 7418 } 7419 } 7420 } 7421 7422 ResolveNamesVisitor &resolver_; 7423 bool pushedScope_{false}; 7424 }; 7425 7426 // Perform checks and completions that need to happen after all of 7427 // the specification parts but before any of the execution parts. 7428 void ResolveNamesVisitor::FinishSpecificationParts(const ProgramTree &node) { 7429 if (!node.scope()) { 7430 return; // error occurred creating scope 7431 } 7432 SetScope(*node.scope()); 7433 // The initializers of pointers, the default initializers of pointer 7434 // components, and non-deferred type-bound procedure bindings have not 7435 // yet been traversed. 7436 // We do that now, when any (formerly) forward references that appear 7437 // in those initializers will resolve to the right symbols without 7438 // incurring spurious errors with IMPLICIT NONE. 7439 DeferredCheckVisitor{*this}.Walk(node.spec()); 7440 DeferredCheckVisitor{*this}.Walk(node.exec()); // for BLOCK 7441 for (Scope &childScope : currScope().children()) { 7442 if (childScope.IsParameterizedDerivedTypeInstantiation()) { 7443 FinishDerivedTypeInstantiation(childScope); 7444 } 7445 } 7446 for (const auto &child : node.children()) { 7447 FinishSpecificationParts(child); 7448 } 7449 } 7450 7451 // Duplicate and fold component object pointer default initializer designators 7452 // using the actual type parameter values of each particular instantiation. 7453 // Validation is done later in declaration checking. 7454 void ResolveNamesVisitor::FinishDerivedTypeInstantiation(Scope &scope) { 7455 CHECK(scope.IsDerivedType() && !scope.symbol()); 7456 if (DerivedTypeSpec * spec{scope.derivedTypeSpec()}) { 7457 spec->Instantiate(currScope()); 7458 const Symbol &origTypeSymbol{spec->typeSymbol()}; 7459 if (const Scope * origTypeScope{origTypeSymbol.scope()}) { 7460 CHECK(origTypeScope->IsDerivedType() && 7461 origTypeScope->symbol() == &origTypeSymbol); 7462 auto &foldingContext{GetFoldingContext()}; 7463 auto restorer{foldingContext.WithPDTInstance(*spec)}; 7464 for (auto &pair : scope) { 7465 Symbol &comp{*pair.second}; 7466 const Symbol &origComp{DEREF(FindInScope(*origTypeScope, comp.name()))}; 7467 if (IsPointer(comp)) { 7468 if (auto *details{comp.detailsIf<ObjectEntityDetails>()}) { 7469 auto origDetails{origComp.get<ObjectEntityDetails>()}; 7470 if (const MaybeExpr & init{origDetails.init()}) { 7471 SomeExpr newInit{*init}; 7472 MaybeExpr folded{ 7473 evaluate::Fold(foldingContext, std::move(newInit))}; 7474 details->set_init(std::move(folded)); 7475 } 7476 } 7477 } 7478 } 7479 } 7480 } 7481 } 7482 7483 // Resolve names in the execution part of this node and its children 7484 void ResolveNamesVisitor::ResolveExecutionParts(const ProgramTree &node) { 7485 if (!node.scope()) { 7486 return; // error occurred creating scope 7487 } 7488 SetScope(*node.scope()); 7489 if (const auto *exec{node.exec()}) { 7490 Walk(*exec); 7491 } 7492 FinishNamelists(); 7493 PopScope(); // converts unclassified entities into objects 7494 for (const auto &child : node.children()) { 7495 ResolveExecutionParts(child); 7496 } 7497 } 7498 7499 void ResolveNamesVisitor::Post(const parser::Program &) { 7500 // ensure that all temps were deallocated 7501 CHECK(!attrs_); 7502 CHECK(!GetDeclTypeSpec()); 7503 } 7504 7505 // A singleton instance of the scope -> IMPLICIT rules mapping is 7506 // shared by all instances of ResolveNamesVisitor and accessed by this 7507 // pointer when the visitors (other than the top-level original) are 7508 // constructed. 7509 static ImplicitRulesMap *sharedImplicitRulesMap{nullptr}; 7510 7511 bool ResolveNames( 7512 SemanticsContext &context, const parser::Program &program, Scope &top) { 7513 ImplicitRulesMap implicitRulesMap; 7514 auto restorer{common::ScopedSet(sharedImplicitRulesMap, &implicitRulesMap)}; 7515 ResolveNamesVisitor{context, implicitRulesMap, top}.Walk(program); 7516 return !context.AnyFatalError(); 7517 } 7518 7519 // Processes a module (but not internal) function when it is referenced 7520 // in a specification expression in a sibling procedure. 7521 void ResolveSpecificationParts( 7522 SemanticsContext &context, const Symbol &subprogram) { 7523 auto originalLocation{context.location()}; 7524 ImplicitRulesMap implicitRulesMap; 7525 bool localImplicitRulesMap{false}; 7526 if (!sharedImplicitRulesMap) { 7527 sharedImplicitRulesMap = &implicitRulesMap; 7528 localImplicitRulesMap = true; 7529 } 7530 ResolveNamesVisitor visitor{ 7531 context, *sharedImplicitRulesMap, context.globalScope()}; 7532 const auto &details{subprogram.get<SubprogramNameDetails>()}; 7533 ProgramTree &node{details.node()}; 7534 const Scope &moduleScope{subprogram.owner()}; 7535 if (localImplicitRulesMap) { 7536 visitor.BeginScope(const_cast<Scope &>(moduleScope)); 7537 } else { 7538 visitor.SetScope(const_cast<Scope &>(moduleScope)); 7539 } 7540 visitor.ResolveSpecificationParts(node); 7541 context.set_location(std::move(originalLocation)); 7542 if (localImplicitRulesMap) { 7543 sharedImplicitRulesMap = nullptr; 7544 } 7545 } 7546 7547 } // namespace Fortran::semantics 7548