[flang-commits] [PATCH] D134471: [flang] Allow a generic-spec on a PUBLIC/PRIVATE statement to declare a generic

Peter Klausler via Phabricator via flang-commits flang-commits at lists.llvm.org
Thu Sep 22 12:57:31 PDT 2022


klausler created this revision.
klausler added a reviewer: PeteSteinfeld.
klausler added a project: Flang.
Herald added a subscriber: jdoerfert.
Herald added a reviewer: sscalpone.
Herald added a project: All.
klausler requested review of this revision.

A generic-spec can appear on a module accessibility control statement
even if it has not been declared as a generic interface, because there's
nothing else that it could be.

While here, simplify the parse tree and parser for AccessId, since
one of its alternatives is ambiguous with the other.


https://reviews.llvm.org/D134471

Files:
  flang/include/flang/Parser/parse-tree.h
  flang/lib/Parser/Fortran-parsers.cpp
  flang/lib/Semantics/resolve-names.cpp
  flang/test/Semantics/modfile51.f90


Index: flang/test/Semantics/modfile51.f90
===================================================================
--- /dev/null
+++ flang/test/Semantics/modfile51.f90
@@ -0,0 +1,21 @@
+! RUN: %python %S/test_modfile.py %s %flang_fc1
+! Allow a generic spec that is not a name to be declared on an
+! accessibility control statement
+module m
+  public :: assignment(=)
+  public :: read(unformatted)
+  public :: operator(.eq.)
+  public :: operator(.smooth.)
+end module
+
+!Expect: m.mod
+!module m
+!interface assignment(=)
+!end interface
+!interface read(unformatted)
+!end interface
+!interface operator(.eq.)
+!end interface
+!interface operator(.smooth.)
+!end interface
+!end
Index: flang/lib/Semantics/resolve-names.cpp
===================================================================
--- flang/lib/Semantics/resolve-names.cpp
+++ flang/lib/Semantics/resolve-names.cpp
@@ -7041,24 +7041,12 @@
     defaultAccess_ = accessAttr;
   } else {
     for (const auto &accessId : accessIds) {
-      common::visit(
-          common::visitors{
-              [=](const parser::Name &y) {
-                Resolve(y, SetAccess(y.source, accessAttr));
-              },
-              [=](const Indirection<parser::GenericSpec> &y) {
-                auto info{GenericSpecInfo{y.value()}};
-                const auto &symbolName{info.symbolName()};
-                if (auto *symbol{FindInScope(symbolName)}) {
-                  info.Resolve(&SetAccess(symbolName, accessAttr, symbol));
-                } else if (info.kind().IsName()) {
-                  info.Resolve(&SetAccess(symbolName, accessAttr));
-                } else {
-                  Say(symbolName, "Generic spec '%s' not found"_err_en_US);
-                }
-              },
-          },
-          accessId.u);
+      GenericSpecInfo info{accessId.v.value()};
+      auto *symbol{FindInScope(info.symbolName())};
+      if (!symbol && !info.kind().IsName()) {
+        symbol = &MakeSymbol(info.symbolName(), Attrs{}, GenericDetails{});
+      }
+      info.Resolve(&SetAccess(info.symbolName(), accessAttr, symbol));
     }
   }
   return false;
Index: flang/lib/Parser/Fortran-parsers.cpp
===================================================================
--- flang/lib/Parser/Fortran-parsers.cpp
+++ flang/lib/Parser/Fortran-parsers.cpp
@@ -758,8 +758,8 @@
             Parser<AccessId>{}))))
 
 // R828 access-id -> access-name | generic-spec
-TYPE_PARSER(construct<AccessId>(indirect(genericSpec)) ||
-    construct<AccessId>(name)) // initially ambiguous with genericSpec
+// "access-name" is ambiguous with "generic-spec"
+TYPE_PARSER(construct<AccessId>(indirect(genericSpec)))
 
 // R829 allocatable-stmt -> ALLOCATABLE [::] allocatable-decl-list
 TYPE_PARSER(construct<AllocatableStmt>("ALLOCATABLE" >> maybe("::"_tok) >>
Index: flang/include/flang/Parser/parse-tree.h
===================================================================
--- flang/include/flang/Parser/parse-tree.h
+++ flang/include/flang/Parser/parse-tree.h
@@ -1356,10 +1356,8 @@
 };
 
 // R828 access-id -> access-name | generic-spec
-struct AccessId {
-  UNION_CLASS_BOILERPLATE(AccessId);
-  std::variant<Name, common::Indirection<GenericSpec>> u;
-};
+// "access-name" is ambiguous with "generic-spec", so that's what's parsed
+WRAPPER_CLASS(AccessId, common::Indirection<GenericSpec>);
 
 // R827 access-stmt -> access-spec [[::] access-id-list]
 struct AccessStmt {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D134471.462272.patch
Type: text/x-patch
Size: 3427 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20220922/be105ff2/attachment-0001.bin>


More information about the flang-commits mailing list