@@ -1635,6 +1635,8 @@ class ResolveNamesVisitor : public virtual ScopeHandler,
1635
1635
void FinishDerivedTypeInstantiation (Scope &);
1636
1636
void ResolveExecutionParts (const ProgramTree &);
1637
1637
void UseCUDABuiltinNames ();
1638
+ void HandleDerivedTypesInImplicitStmts (const parser::ImplicitPart &,
1639
+ const std::list<parser::DeclarationConstruct> &);
1638
1640
};
1639
1641
1640
1642
// ImplicitRules implementation
@@ -2035,6 +2037,7 @@ bool ImplicitRulesVisitor::Pre(const parser::ImplicitSpec &) {
2035
2037
}
2036
2038
2037
2039
void ImplicitRulesVisitor::Post (const parser::ImplicitSpec &) {
2040
+ set_allowForwardReferenceToDerivedType (false );
2038
2041
EndDeclTypeSpec ();
2039
2042
}
2040
2043
@@ -8329,6 +8332,67 @@ static bool NeedsExplicitType(const Symbol &symbol) {
8329
8332
}
8330
8333
}
8331
8334
8335
+ void ResolveNamesVisitor::HandleDerivedTypesInImplicitStmts (
8336
+ const parser::ImplicitPart &implicitPart,
8337
+ const std::list<parser::DeclarationConstruct> &decls) {
8338
+ // Detect derived type definitions and create symbols for them now if
8339
+ // they appear in IMPLICIT statements so that these forward-looking
8340
+ // references will not be ambiguous with host associations.
8341
+ std::set<SourceName> implicitDerivedTypes;
8342
+ for (const auto &ipStmt : implicitPart.v ) {
8343
+ if (const auto *impl{std::get_if<
8344
+ parser::Statement<common::Indirection<parser::ImplicitStmt>>>(
8345
+ &ipStmt.u )}) {
8346
+ if (const auto *specs{std::get_if<std::list<parser::ImplicitSpec>>(
8347
+ &impl->statement .value ().u )}) {
8348
+ for (const auto &spec : *specs) {
8349
+ const auto &declTypeSpec{
8350
+ std::get<parser::DeclarationTypeSpec>(spec.t )};
8351
+ if (const auto *dtSpec{common::visit (
8352
+ common::visitors{
8353
+ [](const parser::DeclarationTypeSpec::Type &x) {
8354
+ return &x.derived ;
8355
+ },
8356
+ [](const parser::DeclarationTypeSpec::Class &x) {
8357
+ return &x.derived ;
8358
+ },
8359
+ [](const auto &) -> const parser::DerivedTypeSpec * {
8360
+ return nullptr ;
8361
+ }},
8362
+ declTypeSpec.u )}) {
8363
+ implicitDerivedTypes.emplace (
8364
+ std::get<parser::Name>(dtSpec->t ).source );
8365
+ }
8366
+ }
8367
+ }
8368
+ }
8369
+ }
8370
+ if (!implicitDerivedTypes.empty ()) {
8371
+ for (const auto &decl : decls) {
8372
+ if (const auto *spec{
8373
+ std::get_if<parser::SpecificationConstruct>(&decl.u )}) {
8374
+ if (const auto *dtDef{
8375
+ std::get_if<common::Indirection<parser::DerivedTypeDef>>(
8376
+ &spec->u )}) {
8377
+ const parser::DerivedTypeStmt &dtStmt{
8378
+ std::get<parser::Statement<parser::DerivedTypeStmt>>(
8379
+ dtDef->value ().t )
8380
+ .statement };
8381
+ const parser::Name &name{std::get<parser::Name>(dtStmt.t )};
8382
+ if (implicitDerivedTypes.find (name.source ) !=
8383
+ implicitDerivedTypes.end () &&
8384
+ !FindInScope (name)) {
8385
+ DerivedTypeDetails details;
8386
+ details.set_isForwardReferenced (true );
8387
+ Resolve (name, MakeSymbol (name, std::move (details)));
8388
+ implicitDerivedTypes.erase (name.source );
8389
+ }
8390
+ }
8391
+ }
8392
+ }
8393
+ }
8394
+ }
8395
+
8332
8396
bool ResolveNamesVisitor::Pre (const parser::SpecificationPart &x) {
8333
8397
const auto &[accDecls, ompDecls, compilerDirectives, useStmts, importStmts,
8334
8398
implicitPart, decls] = x.t ;
@@ -8347,6 +8411,7 @@ bool ResolveNamesVisitor::Pre(const parser::SpecificationPart &x) {
8347
8411
ClearUseOnly ();
8348
8412
ClearModuleUses ();
8349
8413
Walk (importStmts);
8414
+ HandleDerivedTypesInImplicitStmts (implicitPart, decls);
8350
8415
Walk (implicitPart);
8351
8416
for (const auto &decl : decls) {
8352
8417
if (const auto *spec{
0 commit comments