@@ -888,7 +888,8 @@ class SubprogramVisitor : public virtual ScopeHandler, public InterfaceVisitor {
888
888
void CheckExtantProc (const parser::Name &, Symbol::Flag);
889
889
// Create a subprogram symbol in the current scope and push a new scope.
890
890
Symbol &PushSubprogramScope (const parser::Name &, Symbol::Flag,
891
- const parser::LanguageBindingSpec * = nullptr );
891
+ const parser::LanguageBindingSpec * = nullptr ,
892
+ bool hasModulePrefix = false );
892
893
Symbol *GetSpecificFromGeneric (const parser::Name &);
893
894
Symbol &PostSubprogramStmt ();
894
895
void CreateDummyArgument (SubprogramDetails &, const parser::Name &);
@@ -3601,20 +3602,33 @@ void SubprogramVisitor::Post(const parser::PrefixSpec::Cluster_Dims &x) {
3601
3602
}
3602
3603
}
3603
3604
3605
+ static bool HasModulePrefix (const std::list<parser::PrefixSpec> &prefixes) {
3606
+ for (const auto &prefix : prefixes) {
3607
+ if (std::holds_alternative<parser::PrefixSpec::Module>(prefix.u )) {
3608
+ return true ;
3609
+ }
3610
+ }
3611
+ return false ;
3612
+ }
3613
+
3604
3614
bool SubprogramVisitor::Pre (const parser::InterfaceBody::Subroutine &x) {
3605
- const auto &name{std::get<parser::Name>(
3606
- std::get<parser::Statement<parser::SubroutineStmt>>(x.t ).statement .t )};
3607
- return BeginSubprogram (name, Symbol::Flag::Subroutine);
3615
+ const auto &stmtTuple{
3616
+ std::get<parser::Statement<parser::SubroutineStmt>>(x.t ).statement .t };
3617
+ return BeginSubprogram (std::get<parser::Name>(stmtTuple),
3618
+ Symbol::Flag::Subroutine,
3619
+ HasModulePrefix (std::get<std::list<parser::PrefixSpec>>(stmtTuple)));
3608
3620
}
3609
3621
void SubprogramVisitor::Post (const parser::InterfaceBody::Subroutine &x) {
3610
3622
const auto &stmt{std::get<parser::Statement<parser::SubroutineStmt>>(x.t )};
3611
3623
EndSubprogram (stmt.source ,
3612
3624
&std::get<std::optional<parser::LanguageBindingSpec>>(stmt.statement .t ));
3613
3625
}
3614
3626
bool SubprogramVisitor::Pre (const parser::InterfaceBody::Function &x) {
3615
- const auto &name{std::get<parser::Name>(
3616
- std::get<parser::Statement<parser::FunctionStmt>>(x.t ).statement .t )};
3617
- return BeginSubprogram (name, Symbol::Flag::Function);
3627
+ const auto &stmtTuple{
3628
+ std::get<parser::Statement<parser::FunctionStmt>>(x.t ).statement .t };
3629
+ return BeginSubprogram (std::get<parser::Name>(stmtTuple),
3630
+ Symbol::Flag::Function,
3631
+ HasModulePrefix (std::get<std::list<parser::PrefixSpec>>(stmtTuple)));
3618
3632
}
3619
3633
void SubprogramVisitor::Post (const parser::InterfaceBody::Function &x) {
3620
3634
const auto &stmt{std::get<parser::Statement<parser::FunctionStmt>>(x.t )};
@@ -4023,10 +4037,16 @@ bool SubprogramVisitor::BeginSubprogram(const parser::Name &name,
4023
4037
if (moduleInterface && &moduleInterface->owner () == &currScope ()) {
4024
4038
// Subprogram is MODULE FUNCTION or MODULE SUBROUTINE with an interface
4025
4039
// previously defined in the same scope.
4026
- EraseSymbol (name);
4040
+ if (GenericDetails *
4041
+ generic{DEREF (FindSymbol (name)).detailsIf <GenericDetails>()}) {
4042
+ generic->clear_specific ();
4043
+ } else {
4044
+ EraseSymbol (name);
4045
+ }
4027
4046
}
4028
4047
}
4029
- Symbol &newSymbol{PushSubprogramScope (name, subpFlag, bindingSpec)};
4048
+ Symbol &newSymbol{
4049
+ PushSubprogramScope (name, subpFlag, bindingSpec, hasModulePrefix)};
4030
4050
if (moduleInterface) {
4031
4051
newSymbol.get <SubprogramDetails>().set_moduleInterface (*moduleInterface);
4032
4052
if (moduleInterface->attrs ().test (Attr::PRIVATE)) {
@@ -4134,7 +4154,8 @@ void SubprogramVisitor::CheckExtantProc(
4134
4154
}
4135
4155
4136
4156
Symbol &SubprogramVisitor::PushSubprogramScope (const parser::Name &name,
4137
- Symbol::Flag subpFlag, const parser::LanguageBindingSpec *bindingSpec) {
4157
+ Symbol::Flag subpFlag, const parser::LanguageBindingSpec *bindingSpec,
4158
+ bool hasModulePrefix) {
4138
4159
Symbol *symbol{GetSpecificFromGeneric (name)};
4139
4160
if (!symbol) {
4140
4161
if (bindingSpec && currScope ().IsGlobal () && bindingSpec->v ) {
@@ -4159,6 +4180,8 @@ Symbol &SubprogramVisitor::PushSubprogramScope(const parser::Name &name,
4159
4180
details.set_isInterface ();
4160
4181
if (isAbstract ()) {
4161
4182
SetExplicitAttr (*symbol, Attr::ABSTRACT);
4183
+ } else if (hasModulePrefix) {
4184
+ SetExplicitAttr (*symbol, Attr::MODULE);
4162
4185
} else {
4163
4186
MakeExternal (*symbol);
4164
4187
}
@@ -4172,7 +4195,10 @@ Symbol &SubprogramVisitor::PushSubprogramScope(const parser::Name &name,
4172
4195
}
4173
4196
set_inheritFromParent (false );
4174
4197
}
4175
- FindSymbol (name)->set (subpFlag); // PushScope() created symbol
4198
+ if (Symbol * found{FindSymbol (name)};
4199
+ found && found->has <HostAssocDetails>()) {
4200
+ found->set (subpFlag); // PushScope() created symbol
4201
+ }
4176
4202
return *symbol;
4177
4203
}
4178
4204
@@ -4208,6 +4234,7 @@ Symbol *SubprogramVisitor::GetSpecificFromGeneric(const parser::Name &name) {
4208
4234
} else if (auto *details{symbol->detailsIf <GenericDetails>()}) {
4209
4235
// found generic, want specific procedure
4210
4236
auto *specific{details->specific ()};
4237
+ Attrs moduleAttr;
4211
4238
if (inInterfaceBlock ()) {
4212
4239
if (specific) {
4213
4240
// Defining an interface in a generic of the same name which is
@@ -4218,6 +4245,7 @@ Symbol *SubprogramVisitor::GetSpecificFromGeneric(const parser::Name &name) {
4218
4245
// The shadowed procedure is a separate module procedure that is
4219
4246
// actually defined later in this (sub)module.
4220
4247
// Define its interface now as a new symbol.
4248
+ moduleAttr.set (Attr::MODULE);
4221
4249
specific = nullptr ;
4222
4250
} else if (&specific->owner () != &symbol->owner ()) {
4223
4251
// The shadowed procedure was from an enclosing scope and will be
@@ -4236,8 +4264,8 @@ Symbol *SubprogramVisitor::GetSpecificFromGeneric(const parser::Name &name) {
4236
4264
}
4237
4265
}
4238
4266
if (!specific) {
4239
- specific =
4240
- & currScope (). MakeSymbol ( name.source , Attrs{} , SubprogramDetails{});
4267
+ specific = & currScope (). MakeSymbol (
4268
+ name.source , std::move (moduleAttr) , SubprogramDetails{});
4241
4269
if (details->derivedType ()) {
4242
4270
// A specific procedure with the same name as a derived type
4243
4271
SayAlreadyDeclared (name, *details->derivedType ());
0 commit comments