@@ -135,14 +135,15 @@ class MessageHandler {
135
135
// + AttrsVisitor
136
136
// | + DeclTypeSpecVisitor
137
137
// | + ImplicitRulesVisitor
138
- // | + ScopeHandler -----------+--+
139
- // | + ModuleVisitor ========|==+
140
- // | + InterfaceVisitor | |
141
- // | +-+ SubprogramVisitor ==|==+
142
- // + ArraySpecVisitor | |
143
- // + DeclarationVisitor <--------+ |
144
- // + ConstructVisitor |
145
- // + ResolveNamesVisitor <------+
138
+ // | + ScopeHandler ------------------+
139
+ // | + ModuleVisitor -------------+ |
140
+ // | + GenericHandler -------+ | |
141
+ // | | + InterfaceVisitor | | |
142
+ // | +-+ SubprogramVisitor ==|==+ | |
143
+ // + ArraySpecVisitor | | | |
144
+ // + DeclarationVisitor <--------+ | | |
145
+ // + ConstructVisitor | | |
146
+ // + ResolveNamesVisitor <------+-+-+
146
147
147
148
class BaseVisitor {
148
149
public:
@@ -809,7 +810,23 @@ class ModuleVisitor : public virtual ScopeHandler {
809
810
Scope *ancestor = nullptr );
810
811
};
811
812
812
- class InterfaceVisitor : public virtual ScopeHandler {
813
+ class GenericHandler : public virtual ScopeHandler {
814
+ protected:
815
+ using ProcedureKind = parser::ProcedureStmt::Kind;
816
+ void ResolveSpecificsInGeneric (Symbol &, bool isEndOfSpecificationPart);
817
+ void DeclaredPossibleSpecificProc (Symbol &);
818
+
819
+ // Mappings of generics to their as-yet specific proc names and kinds
820
+ using SpecificProcMapType =
821
+ std::multimap<Symbol *, std::pair<const parser::Name *, ProcedureKind>>;
822
+ SpecificProcMapType specificsForGenericProcs_;
823
+ // inversion of SpecificProcMapType: maps pending proc names to generics
824
+ using GenericProcMapType = std::multimap<SourceName, Symbol *>;
825
+ GenericProcMapType genericsForSpecificProcs_;
826
+ };
827
+
828
+ class InterfaceVisitor : public virtual ScopeHandler,
829
+ public virtual GenericHandler {
813
830
public:
814
831
bool Pre (const parser::InterfaceStmt &);
815
832
void Post (const parser::InterfaceStmt &);
@@ -840,15 +857,7 @@ class InterfaceVisitor : public virtual ScopeHandler {
840
857
std::stack<GenericInfo> genericInfo_;
841
858
const GenericInfo &GetGenericInfo () const { return genericInfo_.top (); }
842
859
void SetGenericSymbol (Symbol &symbol) { genericInfo_.top ().symbol = &symbol; }
843
-
844
- using ProcedureKind = parser::ProcedureStmt::Kind;
845
- // mapping of generic to its specific proc names and kinds
846
- using SpecificProcMapType =
847
- std::multimap<Symbol *, std::pair<const parser::Name *, ProcedureKind>>;
848
- SpecificProcMapType specificProcs_;
849
-
850
860
void AddSpecificProcs (const std::list<parser::Name> &, ProcedureKind);
851
- void ResolveSpecificsInGeneric (Symbol &, bool isEndOfSpecificationPart);
852
861
void ResolveNewSpecifics ();
853
862
};
854
863
@@ -904,7 +913,7 @@ class SubprogramVisitor : public virtual ScopeHandler, public InterfaceVisitor {
904
913
};
905
914
906
915
class DeclarationVisitor : public ArraySpecVisitor ,
907
- public virtual ScopeHandler {
916
+ public virtual GenericHandler {
908
917
public:
909
918
using ArraySpecVisitor::Post;
910
919
using ScopeHandler::Post;
@@ -3309,35 +3318,32 @@ bool InterfaceVisitor::isAbstract() const {
3309
3318
3310
3319
void InterfaceVisitor::AddSpecificProcs (
3311
3320
const std::list<parser::Name> &names, ProcedureKind kind) {
3312
- for (const auto &name : names) {
3313
- specificProcs_.emplace (
3314
- GetGenericInfo ().symbol , std::make_pair (&name, kind));
3321
+ if (Symbol * symbol{GetGenericInfo ().symbol };
3322
+ symbol && symbol->has <GenericDetails>()) {
3323
+ for (const auto &name : names) {
3324
+ specificsForGenericProcs_.emplace (symbol, std::make_pair (&name, kind));
3325
+ genericsForSpecificProcs_.emplace (name.source , symbol);
3326
+ }
3315
3327
}
3316
3328
}
3317
3329
3318
3330
// By now we should have seen all specific procedures referenced by name in
3319
3331
// this generic interface. Resolve those names to symbols.
3320
- void InterfaceVisitor ::ResolveSpecificsInGeneric (
3332
+ void GenericHandler ::ResolveSpecificsInGeneric (
3321
3333
Symbol &generic, bool isEndOfSpecificationPart) {
3322
3334
auto &details{generic.get <GenericDetails>()};
3323
3335
UnorderedSymbolSet symbolsSeen;
3324
3336
for (const Symbol &symbol : details.specificProcs ()) {
3325
3337
symbolsSeen.insert (symbol.GetUltimate ());
3326
3338
}
3327
- auto range{specificProcs_ .equal_range (&generic)};
3339
+ auto range{specificsForGenericProcs_ .equal_range (&generic)};
3328
3340
SpecificProcMapType retain;
3329
3341
for (auto it{range.first }; it != range.second ; ++it) {
3330
3342
const parser::Name *name{it->second .first };
3331
3343
auto kind{it->second .second };
3332
- const Symbol *symbol{FindSymbol (*name)};
3333
- if (!isEndOfSpecificationPart && symbol &&
3334
- &symbol->owner () != &generic.owner ()) {
3335
- // Don't mistakenly use a name from the enclosing scope while there's
3336
- // still a chance that it could be overridden by a later declaration in
3337
- // this scope.
3338
- retain.emplace (&generic, std::make_pair (name, kind));
3339
- continue ;
3340
- }
3344
+ const Symbol *symbol{isEndOfSpecificationPart
3345
+ ? FindSymbol (*name)
3346
+ : FindInScope (generic.owner (), *name)};
3341
3347
ProcedureDefinitionClass defClass{ProcedureDefinitionClass::None};
3342
3348
const Symbol *specific{symbol};
3343
3349
const Symbol *ultimate{nullptr };
@@ -3400,8 +3406,15 @@ void InterfaceVisitor::ResolveSpecificsInGeneric(
3400
3406
MakeOpName (generic.name ()));
3401
3407
}
3402
3408
}
3403
- specificProcs_.erase (range.first , range.second );
3404
- specificProcs_.merge (std::move (retain));
3409
+ specificsForGenericProcs_.erase (range.first , range.second );
3410
+ specificsForGenericProcs_.merge (std::move (retain));
3411
+ }
3412
+
3413
+ void GenericHandler::DeclaredPossibleSpecificProc (Symbol &proc) {
3414
+ auto range{genericsForSpecificProcs_.equal_range (proc.name ())};
3415
+ for (auto iter{range.first }; iter != range.second ; ++iter) {
3416
+ ResolveSpecificsInGeneric (*iter->second , false );
3417
+ }
3405
3418
}
3406
3419
3407
3420
void InterfaceVisitor::ResolveNewSpecifics () {
@@ -4141,6 +4154,9 @@ void SubprogramVisitor::EndSubprogram(
4141
4154
}
4142
4155
}
4143
4156
}
4157
+ if (inInterfaceBlock () && currScope ().symbol ()) {
4158
+ DeclaredPossibleSpecificProc (*currScope ().symbol ());
4159
+ }
4144
4160
PopScope ();
4145
4161
}
4146
4162
@@ -5477,6 +5493,7 @@ void DeclarationVisitor::Post(const parser::ProcDecl &x) {
5477
5493
if (dtDetails) {
5478
5494
dtDetails->add_component (symbol);
5479
5495
}
5496
+ DeclaredPossibleSpecificProc (symbol);
5480
5497
}
5481
5498
5482
5499
bool DeclarationVisitor::Pre (const parser::TypeBoundProcedurePart &) {
0 commit comments