[flang] Small .mod file fixes
authorTim Keith <tkeith@nvidia.com>
Mon, 12 Aug 2019 21:06:06 +0000 (14:06 -0700)
committerTim Keith <tkeith@nvidia.com>
Tue, 13 Aug 2019 16:15:50 +0000 (09:15 -0700)
- Only emit initializations for parameters and derived type components.
- Use `=>` for pointer initializations.
- Don't emit intrinsic symbols.

Original-commit: flang-compiler/f18@b91748c053a11349f85645c65b870fab222ea135
Reviewed-on: https://github.com/flang-compiler/f18/pull/650
Tree-same-pre-rewrite: false

flang/lib/semantics/mod-file.cc
flang/test/semantics/modfile20.f90
flang/test/semantics/modfile30.f90

index 114870d..4333ed3 100644 (file)
@@ -46,7 +46,7 @@ static void PutProcEntity(std::ostream &, const Symbol &);
 static void PutPassName(std::ostream &, const SourceName *);
 static void PutTypeParam(std::ostream &, const Symbol &);
 static void PutEntity(std::ostream &, const Symbol &, std::function<void()>);
-static void PutInit(std::ostream &, const MaybeExpr &);
+static void PutInit(std::ostream &, const Symbol &, const MaybeExpr &);
 static void PutInit(std::ostream &, const MaybeIntExpr &);
 static void PutBound(std::ostream &, const Bound &);
 static std::ostream &PutAttrs(std::ostream &, Attrs,
@@ -386,7 +386,8 @@ std::vector<const Symbol *> CollectSymbols(const Scope &scope) {
   sorted.reserve(scope.size() + scope.commonBlocks().size());
   for (const auto &pair : scope) {
     auto *symbol{pair.second};
-    if (!symbol->test(Symbol::Flag::ParentComp)) {
+    if (!symbol->test(Symbol::Flag::ParentComp) &&
+        !symbol->attrs().test(Attr::INTRINSIC)) {
       if (symbols.insert(symbol).second) {
         if (symbol->has<NamelistDetails>()) {
           namelist.push_back(symbol);
@@ -464,7 +465,7 @@ void PutObjectEntity(std::ostream &os, const Symbol &symbol) {
   PutEntity(os, symbol, [&]() { PutLower(os, DEREF(symbol.GetType())); });
   PutShape(os, details.shape(), '(', ')');
   PutShape(os, details.coshape(), '[', ']');
-  PutInit(os, details.init());
+  PutInit(os, symbol, details.init());
   os << '\n';
 }
 
@@ -503,9 +504,13 @@ void PutTypeParam(std::ostream &os, const Symbol &symbol) {
   os << '\n';
 }
 
-void PutInit(std::ostream &os, const MaybeExpr &init) {
+void PutInit(std::ostream &os, const Symbol &symbol, const MaybeExpr &init) {
   if (init) {
-    init->AsFortran(os << '=');
+    if (symbol.attrs().test(Attr::PARAMETER) ||
+        symbol.owner().IsDerivedType()) {
+      os << (symbol.attrs().test(Attr::POINTER) ? "=>" : "=");
+      init->AsFortran(os);
+    }
   }
 }
 
index 4b7096c..da230e4 100644 (file)
@@ -12,7 +12,7 @@
 ! See the License for the specific language governing permissions and
 ! limitations under the License.
 
-! Check modfile generation for generic interfaces
+! Test modfiles for entities with initialization
 module m
   integer, parameter :: k8 = 8
   integer(8), parameter :: k4 = k8/2
@@ -20,7 +20,14 @@ module m
   integer(k8), parameter :: i = 2_k8
   real :: r = 2.0_k4
   character(10, kind=k1) :: c = k1_"asdf"
-  complex*16 :: z = (1.0_k8, 2.0_k8)
+  character(10), parameter :: c2 = k1_"qwer"
+  complex*16, parameter :: z = (1.0_k8, 2.0_k8)
+  type t
+    integer :: a = 123
+    type(t), pointer :: b => null()
+  end type
+  type(t), parameter :: x = t(456)
+  type(t), parameter :: y = t(789, null())
 end
 
 !Expect: m.mod
@@ -29,7 +36,14 @@ end
 !  integer(8),parameter::k4=4_8
 !  integer(4),parameter::k1=1_4
 !  integer(8),parameter::i=2_8
-!  real(4)::r=2._4
-!  character(10_4,1)::c=1_"asdf      "
-!  complex(8)::z=(1._8,2._8)
+!  real(4)::r
+!  character(10_4,1)::c
+!  character(10_4,1),parameter::c2=1_"qwer      "
+!  complex(8),parameter::z=(1._8,2._8)
+!  type::t
+!    integer(4)::a=123_4
+!    type(t),pointer::b=>NULL()
+!  end type
+!  type(t),parameter::x=t(a=456_4,b=NULL())
+!  type(t),parameter::y=t(a=789_4,b=NULL())
 !end
index 0156219..680b807 100644 (file)
@@ -54,3 +54,44 @@ end
 ! end type
 ! type(t),parameter::a=t()
 !end
+
+! Don't write out intrinsics
+module m3a
+  integer, parameter :: i4 = selected_int_kind(9)
+end
+module m3b
+  use m3a
+  integer(i4) :: j
+end
+
+!Expect: m3a.mod
+!module m3a
+! integer(4),parameter::i4=4_4
+!end
+
+!Expect: m3b.mod
+!module m3b
+! use m3a,only:i4
+! integer(4)::j
+!end
+
+! Test that character literals written with backslash escapes are read correctly.
+module m4a
+  character(1), parameter :: a = achar(1)
+end
+module m4b
+  use m4a
+  character(1), parameter :: b = a
+end
+
+!Expect: m4a.mod
+!module m4a
+! character(1_4,1),parameter::a=1_"\001"
+!end
+
+!Expect: m4b.mod
+!module m4b
+! use m4a,only:a
+! character(1_4,1),parameter::b=1_"\001"
+!end
+