summaryrefslogtreecommitdiffstats
path: root/flang/lib/Semantics/program-tree.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Semantics/program-tree.cpp')
-rw-r--r--flang/lib/Semantics/program-tree.cpp37
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