diff options
author | Peter Klausler <pklausler@nvidia.com> | 2022-01-10 10:16:19 -0800 |
---|---|---|
committer | Peter Klausler <pklausler@nvidia.com> | 2022-01-14 15:43:21 -0800 |
commit | bed947f7081353257b78612cf8dfbd161463966c (patch) | |
tree | 5c864c869d65239a7551e3313ab2b9388c113348 /flang/lib/Semantics/program-tree.cpp | |
parent | 8dff860c220c71f314be00ae78be0ded0389e38f (diff) | |
download | llvm-bed947f7081353257b78612cf8dfbd161463966c.zip llvm-bed947f7081353257b78612cf8dfbd161463966c.tar.gz llvm-bed947f7081353257b78612cf8dfbd161463966c.tar.bz2 |
[flang] Accept ENTRY names in generic interfaces
ENTRY statement names in module subprograms were not acceptable for
use as a "module procedure" in a generic interface, but should be.
ENTRY statements need to have symbols with place-holding
SubprogramNameDetails created for them in order to be visible in
generic interfaces. Those symbols are created from the "program
tree" data structure. This patch adds ENTRY statement names to the
program tree data structure and uses them to generate SubprogramNameDetails
symbols.
Differential Revision: https://reviews.llvm.org/D117345
Diffstat (limited to 'flang/lib/Semantics/program-tree.cpp')
-rw-r--r-- | flang/lib/Semantics/program-tree.cpp | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/flang/lib/Semantics/program-tree.cpp b/flang/lib/Semantics/program-tree.cpp index 9466a74..e20299b 100644 --- a/flang/lib/Semantics/program-tree.cpp +++ b/flang/lib/Semantics/program-tree.cpp @@ -13,6 +13,37 @@ namespace Fortran::semantics { +static void GetEntryStmts( + ProgramTree &node, const parser::SpecificationPart &spec) { + const auto &implicitPart{std::get<parser::ImplicitPart>(spec.t)}; + for (const parser::ImplicitPartStmt &stmt : implicitPart.v) { + if (const auto *entryStmt{std::get_if< + parser::Statement<common::Indirection<parser::EntryStmt>>>( + &stmt.u)}) { + node.AddEntry(entryStmt->statement.value()); + } + } + for (const auto &decl : + std::get<std::list<parser::DeclarationConstruct>>(spec.t)) { + if (const auto *entryStmt{std::get_if< + parser::Statement<common::Indirection<parser::EntryStmt>>>( + &decl.u)}) { + node.AddEntry(entryStmt->statement.value()); + } + } +} + +static void GetEntryStmts( + ProgramTree &node, const parser::ExecutionPart &exec) { + for (const auto &epConstruct : exec.v) { + if (const auto *entryStmt{std::get_if< + parser::Statement<common::Indirection<parser::EntryStmt>>>( + &epConstruct.u)}) { + node.AddEntry(entryStmt->statement.value()); + } + } +} + template <typename T> static ProgramTree BuildSubprogramTree(const parser::Name &name, const T &x) { const auto &spec{std::get<parser::SpecificationPart>(x.t)}; @@ -20,6 +51,8 @@ static ProgramTree BuildSubprogramTree(const parser::Name &name, const T &x) { const auto &subps{ std::get<std::optional<parser::InternalSubprogramPart>>(x.t)}; ProgramTree node{name, spec, &exec}; + GetEntryStmts(node, spec); + GetEntryStmts(node, exec); if (subps) { for (const auto &subp : std::get<std::list<parser::InternalSubprogram>>(subps->t)) { @@ -34,7 +67,7 @@ static ProgramTree BuildSubprogramTree(const parser::Name &name, const T &x) { static ProgramTree BuildSubprogramTree( const parser::Name &name, const parser::BlockData &x) { const auto &spec{std::get<parser::SpecificationPart>(x.t)}; - return ProgramTree{name, spec, nullptr}; + return ProgramTree{name, spec}; } template <typename T> @@ -193,4 +226,8 @@ void ProgramTree::AddChild(ProgramTree &&child) { children_.emplace_back(std::move(child)); } +void ProgramTree::AddEntry(const parser::EntryStmt &entryStmt) { + entryStmts_.emplace_back(entryStmt); +} + } // namespace Fortran::semantics |