[flang] External I/O runtime work, repackaged (part 1)

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
This commit is contained in:
peter klausler 2020-07-02 14:11:14 -07:00
parent ca464639a1
commit 37f98f6f4c
2 changed files with 12 additions and 5 deletions

View 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

View 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>;