diff options
Diffstat (limited to 'flang/lib/Semantics/program-tree.cpp')
-rw-r--r-- | flang/lib/Semantics/program-tree.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/flang/lib/Semantics/program-tree.cpp b/flang/lib/Semantics/program-tree.cpp index e20299b2fb4c..9d76cfad8380 100644 --- a/flang/lib/Semantics/program-tree.cpp +++ b/flang/lib/Semantics/program-tree.cpp @@ -44,6 +44,37 @@ static void GetEntryStmts( } } +// Collects generics that define simple names that could include +// identically-named subprograms as specific procedures. +static void GetGenerics( + ProgramTree &node, const parser::SpecificationPart &spec) { + for (const auto &decl : + std::get<std::list<parser::DeclarationConstruct>>(spec.t)) { + if (const auto *spec{ + std::get_if<parser::SpecificationConstruct>(&decl.u)}) { + if (const auto *generic{std::get_if< + parser::Statement<common::Indirection<parser::GenericStmt>>>( + &spec->u)}) { + const parser::GenericStmt &genericStmt{generic->statement.value()}; + const auto &genericSpec{std::get<parser::GenericSpec>(genericStmt.t)}; + node.AddGeneric(genericSpec); + } else if (const auto *interface{ + std::get_if<common::Indirection<parser::InterfaceBlock>>( + &spec->u)}) { + const parser::InterfaceBlock &interfaceBlock{interface->value()}; + const parser::InterfaceStmt &interfaceStmt{ + std::get<parser::Statement<parser::InterfaceStmt>>(interfaceBlock.t) + .statement}; + const auto *genericSpec{ + std::get_if<std::optional<parser::GenericSpec>>(&interfaceStmt.u)}; + if (genericSpec && genericSpec->has_value()) { + node.AddGeneric(**genericSpec); + } + } + } + } +} + template <typename T> static ProgramTree BuildSubprogramTree(const parser::Name &name, const T &x) { const auto &spec{std::get<parser::SpecificationPart>(x.t)}; @@ -53,6 +84,7 @@ static ProgramTree BuildSubprogramTree(const parser::Name &name, const T &x) { ProgramTree node{name, spec, &exec}; GetEntryStmts(node, spec); GetEntryStmts(node, exec); + GetGenerics(node, spec); if (subps) { for (const auto &subp : std::get<std::list<parser::InternalSubprogram>>(subps->t)) { @@ -75,6 +107,7 @@ static ProgramTree BuildModuleTree(const parser::Name &name, const T &x) { const auto &spec{std::get<parser::SpecificationPart>(x.t)}; const auto &subps{std::get<std::optional<parser::ModuleSubprogramPart>>(x.t)}; ProgramTree node{name, spec}; + GetGenerics(node, spec); if (subps) { for (const auto &subp : std::get<std::list<parser::ModuleSubprogram>>(subps->t)) { @@ -230,4 +263,8 @@ void ProgramTree::AddEntry(const parser::EntryStmt &entryStmt) { entryStmts_.emplace_back(entryStmt); } +void ProgramTree::AddGeneric(const parser::GenericSpec &generic) { + genericSpecs_.emplace_back(generic); +} + } // namespace Fortran::semantics |