aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Semantics/program-tree.cpp
diff options
context:
space:
mode:
authorPeter Klausler <pklausler@nvidia.com>2022-01-10 10:16:19 -0800
committerPeter Klausler <pklausler@nvidia.com>2022-01-14 15:43:21 -0800
commitbed947f7081353257b78612cf8dfbd161463966c (patch)
tree5c864c869d65239a7551e3313ab2b9388c113348 /flang/lib/Semantics/program-tree.cpp
parent8dff860c220c71f314be00ae78be0ded0389e38f (diff)
downloadllvm-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.cpp39
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