OSDN Git Service

[flang] External I/O runtime work, repackaged (part 1)
authorpeter klausler <pklausler@nvidia.com>
Thu, 2 Jul 2020 21:11:14 +0000 (14:11 -0700)
committerpeter klausler <pklausler@nvidia.com>
Thu, 2 Jul 2020 22:17:26 +0000 (15:17 -0700)
Add a isFixedRecordLength flag member to Connection to
disambiguate the state of "record has known variable length"
from "record has fixed length".  Code that sets and tests this
flag will appear in later patches.  Rearrange data members to
reduce storage requirements, since Connection might indirectly
end up on a program stack frame.  Add a utility member function
BeginRecord(); use it in internal I/O processing.

Reviewed By: tskeith, sscalpone

Differential Revision: https://reviews.llvm.org/D83098

flang/runtime/connection.h
flang/runtime/internal-unit.cpp

index d45ccfb..ba1e27c 100644 (file)
@@ -26,9 +26,10 @@ inline bool IsRecordFile(Access a) { return a != Access::Stream; }
 // established in an OPEN statement.
 struct ConnectionAttributes {
   Access access{Access::Sequential}; // ACCESS='SEQUENTIAL', 'DIRECT', 'STREAM'
-  std::optional<std::int64_t> recordLength; // RECL= when fixed-length
   bool isUnformatted{false}; // FORM='UNFORMATTED'
   bool isUTF8{false}; // ENCODING='UTF-8'
+  bool isFixedRecordLength{false}; // RECL= on OPEN
+  std::optional<std::int64_t> recordLength; // RECL= or current record
 };
 
 struct ConnectionState : public ConnectionAttributes {
@@ -37,6 +38,12 @@ struct ConnectionState : public ConnectionAttributes {
   void HandleAbsolutePosition(std::int64_t);
   void HandleRelativePosition(std::int64_t);
 
+  void BeginRecord() {
+    positionInRecord = 0;
+    furthestPositionInRecord = 0;
+    leftTabLimit.reset();
+  }
+
   // Positions in a record file (sequential or direct, not stream)
   std::int64_t currentRecordNumber{1}; // 1 is first
   std::int64_t positionInRecord{0}; // offset in current record
index c051100..9c29123 100644 (file)
@@ -17,6 +17,7 @@ namespace Fortran::runtime::io {
 template <Direction DIR>
 InternalDescriptorUnit<DIR>::InternalDescriptorUnit(
     Scalar scalar, std::size_t length) {
+  isFixedRecordLength = true;
   recordLength = length;
   endfileRecordNumber = 2;
   void *pointer{reinterpret_cast<void *>(const_cast<char *>(scalar))};
@@ -33,6 +34,7 @@ InternalDescriptorUnit<DIR>::InternalDescriptorUnit(
       terminator, that.SizeInBytes() <= d.SizeInBytes(maxRank, true, 0));
   new (&d) Descriptor{that};
   d.Check();
+  isFixedRecordLength = true;
   recordLength = d.ElementBytes();
   endfileRecordNumber = d.Elements() + 1;
 }
@@ -123,8 +125,7 @@ bool InternalDescriptorUnit<DIR>::AdvanceRecord(IoErrorHandler &handler) {
     }
   }
   ++currentRecordNumber;
-  positionInRecord = 0;
-  furthestPositionInRecord = 0;
+  BeginRecord();
   return true;
 }
 
@@ -132,8 +133,7 @@ template <Direction DIR>
 void InternalDescriptorUnit<DIR>::BackspaceRecord(IoErrorHandler &handler) {
   RUNTIME_CHECK(handler, currentRecordNumber > 1);
   --currentRecordNumber;
-  positionInRecord = 0;
-  furthestPositionInRecord = 0;
+  BeginRecord();
 }
 
 template class InternalDescriptorUnit<Direction::Output>;