@@ -809,7 +809,6 @@ class SubprogramVisitor : public virtual ScopeHandler, public InterfaceVisitor {
809
809
public:
810
810
bool HandleStmtFunction (const parser::StmtFunctionStmt &);
811
811
bool Pre (const parser::SubroutineStmt &);
812
- void Post (const parser::SubroutineStmt &);
813
812
bool Pre (const parser::FunctionStmt &);
814
813
void Post (const parser::FunctionStmt &);
815
814
bool Pre (const parser::EntryStmt &);
@@ -827,7 +826,8 @@ class SubprogramVisitor : public virtual ScopeHandler, public InterfaceVisitor {
827
826
const ProgramTree::EntryStmtList * = nullptr );
828
827
bool BeginMpSubprogram (const parser::Name &);
829
828
void PushBlockDataScope (const parser::Name &);
830
- void EndSubprogram ();
829
+ void EndSubprogram (
830
+ const std::optional<parser::LanguageBindingSpec> * = nullptr );
831
831
832
832
protected:
833
833
// Set when we see a stmt function that is really an array element assignment
@@ -3208,7 +3208,9 @@ bool SubprogramVisitor::Pre(const parser::Suffix &suffix) {
3208
3208
}
3209
3209
}
3210
3210
}
3211
- return true ;
3211
+ // LanguageBindingSpec deferred to Post(EntryStmt) or, for FunctionStmt,
3212
+ // all the way to EndSubprogram().
3213
+ return false ;
3212
3214
}
3213
3215
3214
3216
bool SubprogramVisitor::Pre (const parser::PrefixSpec &x) {
@@ -3234,30 +3236,27 @@ bool SubprogramVisitor::Pre(const parser::InterfaceBody::Subroutine &x) {
3234
3236
std::get<parser::Statement<parser::SubroutineStmt>>(x.t ).statement .t )};
3235
3237
return BeginSubprogram (name, Symbol::Flag::Subroutine);
3236
3238
}
3237
- void SubprogramVisitor::Post (const parser::InterfaceBody::Subroutine &) {
3238
- EndSubprogram ();
3239
+ void SubprogramVisitor::Post (const parser::InterfaceBody::Subroutine &x) {
3240
+ EndSubprogram (&std::get<std::optional<parser::LanguageBindingSpec>>(
3241
+ std::get<parser::Statement<parser::SubroutineStmt>>(x.t ).statement .t ));
3239
3242
}
3240
3243
bool SubprogramVisitor::Pre (const parser::InterfaceBody::Function &x) {
3241
3244
const auto &name{std::get<parser::Name>(
3242
3245
std::get<parser::Statement<parser::FunctionStmt>>(x.t ).statement .t )};
3243
3246
return BeginSubprogram (name, Symbol::Flag::Function);
3244
3247
}
3245
- void SubprogramVisitor::Post (const parser::InterfaceBody::Function &) {
3246
- EndSubprogram ();
3247
- }
3248
-
3249
- bool SubprogramVisitor::Pre (const parser::SubroutineStmt &) {
3250
- return BeginAttrs ();
3251
- }
3252
- bool SubprogramVisitor::Pre (const parser::FunctionStmt &) {
3253
- FuncResultStack::FuncInfo &info{DEREF (funcResultStack ().Top ())};
3254
- CHECK (!info.inFunctionStmt );
3255
- info.inFunctionStmt = true ;
3256
- return BeginAttrs ();
3248
+ void SubprogramVisitor::Post (const parser::InterfaceBody::Function &x) {
3249
+ const auto &maybeSuffix{std::get<std::optional<parser::Suffix>>(
3250
+ std::get<parser::Statement<parser::FunctionStmt>>(x.t ).statement .t )};
3251
+ EndSubprogram (maybeSuffix ? &maybeSuffix->binding : nullptr );
3257
3252
}
3258
- bool SubprogramVisitor::Pre (const parser::EntryStmt &) { return BeginAttrs (); }
3259
3253
3260
- void SubprogramVisitor::Post (const parser::SubroutineStmt &stmt) {
3254
+ bool SubprogramVisitor::Pre (const parser::SubroutineStmt &stmt) {
3255
+ BeginAttrs ();
3256
+ Walk (std::get<std::list<parser::PrefixSpec>>(stmt.t ));
3257
+ Walk (std::get<parser::Name>(stmt.t ));
3258
+ Walk (std::get<std::list<parser::DummyArg>>(stmt.t ));
3259
+ // Don't traverse the LanguageBindingSpec now; it's deferred to EndSubprogram.
3261
3260
const auto &name{std::get<parser::Name>(stmt.t )};
3262
3261
auto &details{PostSubprogramStmt (name)};
3263
3262
for (const auto &dummyArg : std::get<std::list<parser::DummyArg>>(stmt.t )) {
@@ -3268,7 +3267,15 @@ void SubprogramVisitor::Post(const parser::SubroutineStmt &stmt) {
3268
3267
details.add_alternateReturn ();
3269
3268
}
3270
3269
}
3270
+ return false ;
3271
3271
}
3272
+ bool SubprogramVisitor::Pre (const parser::FunctionStmt &) {
3273
+ FuncResultStack::FuncInfo &info{DEREF (funcResultStack ().Top ())};
3274
+ CHECK (!info.inFunctionStmt );
3275
+ info.inFunctionStmt = true ;
3276
+ return BeginAttrs ();
3277
+ }
3278
+ bool SubprogramVisitor::Pre (const parser::EntryStmt &) { return BeginAttrs (); }
3272
3279
3273
3280
void SubprogramVisitor::Post (const parser::FunctionStmt &stmt) {
3274
3281
const auto &name{std::get<parser::Name>(stmt.t )};
@@ -3340,11 +3347,6 @@ void SubprogramVisitor::Post(const parser::FunctionStmt &stmt) {
3340
3347
SubprogramDetails &SubprogramVisitor::PostSubprogramStmt (
3341
3348
const parser::Name &name) {
3342
3349
Symbol &symbol{*currScope ().symbol ()};
3343
- auto &subp{symbol.get <SubprogramDetails>()};
3344
- SetBindNameOn (symbol);
3345
- CHECK (name.source == symbol.name () ||
3346
- (subp.bindName () && symbol.owner ().IsGlobal () &&
3347
- context ().IsTempName (symbol.name ().ToString ())));
3348
3350
symbol.attrs () |= EndAttrs ();
3349
3351
if (symbol.attrs ().test (Attr::MODULE)) {
3350
3352
symbol.attrs ().set (Attr::EXTERNAL, false );
@@ -3353,6 +3355,9 @@ SubprogramDetails &SubprogramVisitor::PostSubprogramStmt(
3353
3355
}
3354
3356
3355
3357
void SubprogramVisitor::Post (const parser::EntryStmt &stmt) {
3358
+ if (const auto &suffix{std::get<std::optional<parser::Suffix>>(stmt.t )}) {
3359
+ Walk (suffix->binding );
3360
+ }
3356
3361
PostEntryStmt (stmt);
3357
3362
EndAttrs ();
3358
3363
}
@@ -3592,7 +3597,19 @@ bool SubprogramVisitor::BeginSubprogram(const parser::Name &name,
3592
3597
return true ;
3593
3598
}
3594
3599
3595
- void SubprogramVisitor::EndSubprogram () { PopScope (); }
3600
+ void SubprogramVisitor::EndSubprogram (
3601
+ const std::optional<parser::LanguageBindingSpec> *binding) {
3602
+ if (binding && *binding && currScope ().symbol ()) {
3603
+ // Finally process the BIND(C,NAME=name) now that symbols in the name
3604
+ // expression will resolve local names.
3605
+ auto flagRestorer{common::ScopedSet (inSpecificationPart_, false )};
3606
+ BeginAttrs ();
3607
+ Walk (**binding);
3608
+ SetBindNameOn (*currScope ().symbol ());
3609
+ currScope ().symbol ()->attrs () |= EndAttrs ();
3610
+ }
3611
+ PopScope ();
3612
+ }
3596
3613
3597
3614
bool SubprogramVisitor::HandlePreviousCalls (
3598
3615
const parser::Name &name, Symbol &symbol, Symbol::Flag subpFlag) {
@@ -7421,7 +7438,27 @@ bool ResolveNamesVisitor::BeginScopeForNode(const ProgramTree &node) {
7421
7438
}
7422
7439
7423
7440
void ResolveNamesVisitor::EndScopeForNode (const ProgramTree &node) {
7424
- EndSubprogram ();
7441
+ using BindingPtr = const std::optional<parser::LanguageBindingSpec> *;
7442
+ EndSubprogram (common::visit (
7443
+ common::visitors{
7444
+ [](const parser::Statement<parser::FunctionStmt> *stmt) {
7445
+ if (stmt) {
7446
+ if (const auto &maybeSuffix{
7447
+ std::get<std::optional<parser::Suffix>>(
7448
+ stmt->statement .t )}) {
7449
+ return &maybeSuffix->binding ;
7450
+ }
7451
+ }
7452
+ return BindingPtr{};
7453
+ },
7454
+ [](const parser::Statement<parser::SubroutineStmt> *stmt) {
7455
+ return stmt ? &std::get<std::optional<parser::LanguageBindingSpec>>(
7456
+ stmt->statement .t )
7457
+ : BindingPtr{};
7458
+ },
7459
+ [](const auto *) { return BindingPtr{}; },
7460
+ },
7461
+ node.stmt ()));
7425
7462
}
7426
7463
7427
7464
// Some analyses and checks, such as the processing of initializers of
0 commit comments