[flang] Handle VOLATILE or ASYNCHRONOUS added to use-associated entity
authorTim Keith <tkeith@nvidia.com>
Tue, 17 Jul 2018 13:39:38 +0000 (06:39 -0700)
committerTim Keith <tkeith@nvidia.com>
Tue, 17 Jul 2018 13:39:38 +0000 (06:39 -0700)
When a symbol is use-associated, the VOLATILE and ASYNCHRONOUS
attributes can be added. When that happens it must be recorded
in the .mod file.

Original-commit: flang-compiler/f18@44fa9e5ba4172f75abe4194e7f58b26a99646cdc
Reviewed-on: https://github.com/flang-compiler/f18/pull/126

flang/lib/semantics/mod-file.cc
flang/test/semantics/CMakeLists.txt
flang/test/semantics/modfile05.f90 [new file with mode: 0644]

index 856cf01..0b2c848 100644 (file)
@@ -60,6 +60,7 @@ private:
   std::string dir_{"."};
   // The mod file consists of uses, declarations, and contained subprograms:
   std::stringstream uses_;
+  std::stringstream useExtraAttrs_;  // attrs added to used entity
   std::stringstream decls_;
   std::stringstream contains_;
   // Any errors encountered during writing:
@@ -74,6 +75,7 @@ private:
   void PutDerivedType(const Symbol &);
   void PutSubprogram(const Symbol &);
   void PutUse(const Symbol &);
+  void PutUseExtraAttr(Attr, const Symbol &, const Symbol &);
   static void PutEntity(std::ostream &, const Symbol &);
   static void PutObjectEntity(std::ostream &, const Symbol &);
   static void PutProcEntity(std::ostream &, const Symbol &);
@@ -131,6 +133,8 @@ std::string ModFileWriter::GetAsString(const std::string &name) {
   all << "module " << name << '\n';
   all << uses_.str();
   uses_.str(""s);
+  all << useExtraAttrs_.str();
+  useExtraAttrs_.str(""s);
   all << decls_.str();
   decls_.str(""s);
   auto str{contains_.str()};
@@ -251,12 +255,24 @@ void ModFileWriter::PutSubprogram(const Symbol &symbol) {
 
 void ModFileWriter::PutUse(const Symbol &symbol) {
   auto &details{symbol.get<UseDetails>()};
+  auto &use{details.symbol()};
   PutLower(uses_ << "use ", details.module());
   PutLower(uses_ << ",only:", symbol);
-  if (details.symbol().name() != symbol.name()) {
-    PutLower(uses_ << "=>", details.symbol());
+  if (use.name() != symbol.name()) {
+    PutLower(uses_ << "=>", use);
   }
   uses_ << '\n';
+  PutUseExtraAttr(Attr::VOLATILE, symbol, use);
+  PutUseExtraAttr(Attr::ASYNCHRONOUS, symbol, use);
+}
+
+// We have "USE local => use" in this module. If attr was added locally
+// (i.e. on local but not on use), also write it out in the mod file.
+void ModFileWriter::PutUseExtraAttr(Attr attr, const Symbol &local, const Symbol &use) {
+  if (local.attrs().test(attr) && !use.attrs().test(attr)) {
+    PutLower(useExtraAttrs_, AttrToString(attr)) << "::";
+    PutLower(useExtraAttrs_, local) << '\n';
+  }
 }
 
 void ModFileWriter::PutEntity(std::ostream &os, const Symbol &symbol) {
index 32d4227..87ca808 100644 (file)
@@ -61,6 +61,7 @@ set(MODFILE_TESTS
   modfile02.f90
   modfile03.f90
   modfile04.f90
+  modfile05.f90
 )
 
 foreach(test ${ERROR_TESTS})
diff --git a/flang/test/semantics/modfile05.f90 b/flang/test/semantics/modfile05.f90
new file mode 100644 (file)
index 0000000..2b63288
--- /dev/null
@@ -0,0 +1,44 @@
+! Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
+!
+! Licensed under the Apache License, Version 2.0 (the "License");
+! you may not use this file except in compliance with the License.
+! You may obtain a copy of the License at
+!
+!     http://www.apache.org/licenses/LICENSE-2.0
+!
+! Unless required by applicable law or agreed to in writing, software
+! distributed under the License is distributed on an "AS IS" BASIS,
+! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+! See the License for the specific language governing permissions and
+! limitations under the License.
+
+! Use-association with VOLATILE or ASYNCHRONOUS
+
+module m1
+  real x
+  integer y
+  volatile z
+contains
+end
+
+module m2
+  use m1
+  volatile x
+  asynchronous y
+end
+
+!Expect: m1.mod
+!module m1
+!real::x
+!integer::y
+!real,volatile::z
+!end
+
+!Expect: m2.mod
+!module m2
+!use m1,only:x
+!use m1,only:y
+!use m1,only:z
+!volatile::x
+!asynchronous::y
+!end