-
Notifications
You must be signed in to change notification settings - Fork 13.7k
[flang] Implement FSEEK and FTELL #133003
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-flang-fir-hlfir @llvm/pr-subscribers-flang-semantics Author: Peter Klausler (klausler) ChangesPatch is 59.78 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/133003.diff 24 Files Affected:
diff --git a/flang-rt/lib/runtime/extensions.cpp b/flang-rt/lib/runtime/extensions.cpp
index 7e9e512778a75..8d6145155eae0 100644
--- a/flang-rt/lib/runtime/extensions.cpp
+++ b/flang-rt/lib/runtime/extensions.cpp
@@ -9,7 +9,9 @@
// These C-coded entry points with Fortran-mangled names implement legacy
// extensions that will eventually be implemented in Fortran.
+#include "unit.h"
#include "flang/Runtime/extensions.h"
+#include "flang/Runtime/iostat-consts.h"
#include "flang-rt/runtime/descriptor.h"
#include "flang-rt/runtime/terminator.h"
#include "flang-rt/runtime/tools.h"
@@ -268,5 +270,33 @@ void FORTRAN_PROCEDURE_NAME(qsort)(int *array, int *len, int *isize,
qsort(array, *len, *isize, compar);
}
+// Extension procedures related to I/O
+
+namespace io {
+std::int32_t RTNAME(Fseek)(int unitNumber, std::int64_t zeroBasedPos,
+ int whence, const char *sourceFileName, int lineNumber) {
+ if (ExternalFileUnit * unit{ExternalFileUnit::LookUp(unitNumber)}) {
+ Terminator terminator{sourceFileName, lineNumber};
+ IoErrorHandler handler{terminator};
+ if (unit->Fseek(
+ zeroBasedPos, static_cast<enum FseekWhence>(whence), handler)) {
+ return IostatOk;
+ } else {
+ return IostatCannotReposition;
+ }
+ } else {
+ return IostatBadUnitNumber;
+ }
+}
+
+std::int64_t RTNAME(Ftell)(int unitNumber) {
+ if (ExternalFileUnit * unit{ExternalFileUnit::LookUp(unitNumber)}) {
+ return unit->InquirePos() - 1; // zero-based result
+ } else {
+ return -1;
+ }
+}
+} // namespace io
+
} // namespace Fortran::runtime
} // extern "C"
diff --git a/flang-rt/lib/runtime/io-api.cpp b/flang-rt/lib/runtime/io-api.cpp
index 0355734c67fcd..2b7ec9134689b 100644
--- a/flang-rt/lib/runtime/io-api.cpp
+++ b/flang-rt/lib/runtime/io-api.cpp
@@ -33,23 +33,6 @@
namespace Fortran::runtime::io {
RT_EXT_API_GROUP_BEGIN
-RT_API_ATTRS const char *InquiryKeywordHashDecode(
- char *buffer, std::size_t n, InquiryKeywordHash hash) {
- if (n < 1) {
- return nullptr;
- }
- char *p{buffer + n};
- *--p = '\0';
- while (hash > 1) {
- if (p < buffer) {
- return nullptr;
- }
- *--p = 'A' + (hash % 26);
- hash /= 26;
- }
- return hash == 1 ? p : nullptr;
-}
-
template <Direction DIR>
RT_API_ATTRS Cookie BeginInternalArrayListIO(const Descriptor &descriptor,
void ** /*scratchArea*/, std::size_t /*scratchBytes*/,
diff --git a/flang-rt/lib/runtime/io-stmt.cpp b/flang-rt/lib/runtime/io-stmt.cpp
index b0823ffd9e703..636351f560b0a 100644
--- a/flang-rt/lib/runtime/io-stmt.cpp
+++ b/flang-rt/lib/runtime/io-stmt.cpp
@@ -79,6 +79,23 @@ bool IoStatementBase::Inquire(InquiryKeywordHash, std::int64_t &) {
return false;
}
+RT_API_ATTRS static const char *InquiryKeywordHashDecode(
+ char *buffer, std::size_t n, InquiryKeywordHash hash) {
+ if (n < 1) {
+ return nullptr;
+ }
+ char *p{buffer + n};
+ *--p = '\0';
+ while (hash > 1) {
+ if (p < buffer) {
+ return nullptr;
+ }
+ *--p = 'A' + (hash % 26);
+ hash /= 26;
+ }
+ return hash == 1 ? p : nullptr;
+}
+
void IoStatementBase::BadInquiryKeywordHashCrash(InquiryKeywordHash inquiry) {
char buffer[16];
const char *decode{InquiryKeywordHashDecode(buffer, sizeof buffer, inquiry)};
diff --git a/flang-rt/lib/runtime/unit.cpp b/flang-rt/lib/runtime/unit.cpp
index 43501aeb48458..2e8a5e34eb123 100644
--- a/flang-rt/lib/runtime/unit.cpp
+++ b/flang-rt/lib/runtime/unit.cpp
@@ -441,14 +441,14 @@ void ExternalFileUnit::Rewind(IoErrorHandler &handler) {
"REWIND(UNIT=%d) on non-sequential file", unitNumber());
} else {
DoImpliedEndfile(handler);
- SetPosition(0, handler);
+ SetPosition(0);
currentRecordNumber = 1;
leftTabLimit.reset();
anyWriteSinceLastPositioning_ = false;
}
}
-void ExternalFileUnit::SetPosition(std::int64_t pos, IoErrorHandler &handler) {
+void ExternalFileUnit::SetPosition(std::int64_t pos) {
frameOffsetInFile_ = pos;
recordOffsetInFrame_ = 0;
if (access == Access::Direct) {
@@ -457,6 +457,19 @@ void ExternalFileUnit::SetPosition(std::int64_t pos, IoErrorHandler &handler) {
BeginRecord();
}
+void ExternalFileUnit::Sought(
+ std::int64_t zeroBasedPos, IoErrorHandler &handler) {
+ SetPosition(zeroBasedPos);
+ if (zeroBasedPos == 0) {
+ currentRecordNumber = 1;
+ } else {
+ // We no longer know which record we're in. Set currentRecordNumber to
+ // a large value from whence we can both advance and backspace.
+ currentRecordNumber = std::numeric_limits<std::int64_t>::max() / 2;
+ endfileRecordNumber.reset();
+ }
+}
+
bool ExternalFileUnit::SetStreamPos(
std::int64_t oneBasedPos, IoErrorHandler &handler) {
if (access != Access::Stream) {
@@ -474,14 +487,31 @@ bool ExternalFileUnit::SetStreamPos(
frameOffsetInFile_ + recordOffsetInFrame_) {
DoImpliedEndfile(handler);
}
- SetPosition(oneBasedPos - 1, handler);
- // We no longer know which record we're in. Set currentRecordNumber to
- // a large value from whence we can both advance and backspace.
- currentRecordNumber = std::numeric_limits<std::int64_t>::max() / 2;
- endfileRecordNumber.reset();
+ Sought(oneBasedPos - 1, handler);
return true;
}
+// GNU FSEEK extension
+RT_API_ATTRS bool ExternalFileUnit::Fseek(std::int64_t zeroBasedPos,
+ enum FseekWhence whence, IoErrorHandler &handler) {
+ if (whence == FseekEnd) {
+ Flush(handler); // updates knownSize_
+ if (auto size{knownSize()}) {
+ zeroBasedPos += *size;
+ } else {
+ return false;
+ }
+ } else if (whence == FseekCurrent) {
+ zeroBasedPos += InquirePos() - 1;
+ }
+ if (zeroBasedPos >= 0) {
+ Sought(zeroBasedPos, handler);
+ return true;
+ } else {
+ return false;
+ }
+}
+
bool ExternalFileUnit::SetDirectRec(
std::int64_t oneBasedRec, IoErrorHandler &handler) {
if (access != Access::Direct) {
@@ -498,7 +528,7 @@ bool ExternalFileUnit::SetDirectRec(
return false;
}
currentRecordNumber = oneBasedRec;
- SetPosition((oneBasedRec - 1) * *openRecl, handler);
+ SetPosition((oneBasedRec - 1) * *openRecl);
return true;
}
diff --git a/flang-rt/lib/runtime/unit.h b/flang-rt/lib/runtime/unit.h
index bb3d3650da34b..34bb1e44f448b 100644
--- a/flang-rt/lib/runtime/unit.h
+++ b/flang-rt/lib/runtime/unit.h
@@ -33,6 +33,12 @@ class UnitMap;
class ChildIo;
class ExternalFileUnit;
+enum FseekWhence {
+ FseekSet = 0,
+ FseekCurrent = 1,
+ FseekEnd = 2,
+};
+
RT_OFFLOAD_VAR_GROUP_BEGIN
// Predefined file units.
extern RT_VAR_ATTRS ExternalFileUnit *defaultInput; // unit 5
@@ -176,8 +182,9 @@ class ExternalFileUnit : public ConnectionState,
RT_API_ATTRS void Endfile(IoErrorHandler &);
RT_API_ATTRS void Rewind(IoErrorHandler &);
RT_API_ATTRS void EndIoStatement();
- RT_API_ATTRS bool SetStreamPos(
- std::int64_t, IoErrorHandler &); // one-based, for POS=
+ RT_API_ATTRS bool SetStreamPos(std::int64_t oneBasedPos, IoErrorHandler &);
+ RT_API_ATTRS bool Fseek(
+ std::int64_t zeroBasedPos, enum FseekWhence, IoErrorHandler &);
RT_API_ATTRS bool SetDirectRec(
std::int64_t, IoErrorHandler &); // one-based, for REC=
RT_API_ATTRS std::int64_t InquirePos() const {
@@ -196,7 +203,8 @@ class ExternalFileUnit : public ConnectionState,
static RT_API_ATTRS UnitMap &CreateUnitMap();
static RT_API_ATTRS UnitMap &GetUnitMap();
RT_API_ATTRS const char *FrameNextInput(IoErrorHandler &, std::size_t);
- RT_API_ATTRS void SetPosition(std::int64_t, IoErrorHandler &); // zero-based
+ RT_API_ATTRS void SetPosition(std::int64_t zeroBasedPos);
+ RT_API_ATTRS void Sought(std::int64_t zeroBasedPos, IoErrorHandler &);
RT_API_ATTRS void BeginSequentialVariableUnformattedInputRecord(
IoErrorHandler &);
RT_API_ATTRS void BeginVariableFormattedInputRecord(IoErrorHandler &);
diff --git a/flang-rt/unittests/Runtime/ExternalIOTest.cpp b/flang-rt/unittests/Runtime/ExternalIOTest.cpp
index c83535ca82bd3..3833e48be3dd6 100644
--- a/flang-rt/unittests/Runtime/ExternalIOTest.cpp
+++ b/flang-rt/unittests/Runtime/ExternalIOTest.cpp
@@ -13,7 +13,7 @@
#include "CrashHandlerFixture.h"
#include "gtest/gtest.h"
#include "flang-rt/runtime/descriptor.h"
-#include "flang/Runtime/io-api-consts.h"
+#include "flang/Runtime/io-api.h"
#include "flang/Runtime/main.h"
#include "flang/Runtime/stop.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/flang-rt/unittests/Runtime/ListInputTest.cpp b/flang-rt/unittests/Runtime/ListInputTest.cpp
index 310c41a5c3fa5..a8f0d4516ceba 100644
--- a/flang-rt/unittests/Runtime/ListInputTest.cpp
+++ b/flang-rt/unittests/Runtime/ListInputTest.cpp
@@ -9,7 +9,7 @@
#include "CrashHandlerFixture.h"
#include "flang-rt/runtime/descriptor.h"
#include "flang-rt/runtime/io-error.h"
-#include "flang/Runtime/io-api-consts.h"
+#include "flang/Runtime/io-api.h"
using namespace Fortran::runtime;
using namespace Fortran::runtime::io;
diff --git a/flang-rt/unittests/Runtime/LogicalFormatTest.cpp b/flang-rt/unittests/Runtime/LogicalFormatTest.cpp
index bc933292181c1..03da1f046eb94 100644
--- a/flang-rt/unittests/Runtime/LogicalFormatTest.cpp
+++ b/flang-rt/unittests/Runtime/LogicalFormatTest.cpp
@@ -8,7 +8,7 @@
#include "CrashHandlerFixture.h"
#include "flang-rt/runtime/descriptor.h"
-#include "flang/Runtime/io-api-consts.h"
+#include "flang/Runtime/io-api.h"
#include <algorithm>
#include <array>
#include <cstring>
diff --git a/flang-rt/unittests/Runtime/Namelist.cpp b/flang-rt/unittests/Runtime/Namelist.cpp
index 040dedb8cd47c..ee4018e491c32 100644
--- a/flang-rt/unittests/Runtime/Namelist.cpp
+++ b/flang-rt/unittests/Runtime/Namelist.cpp
@@ -10,7 +10,7 @@
#include "CrashHandlerFixture.h"
#include "tools.h"
#include "flang-rt/runtime/descriptor.h"
-#include "flang/Runtime/io-api-consts.h"
+#include "flang/Runtime/io-api.h"
#include <algorithm>
#include <cinttypes>
#include <complex>
diff --git a/flang-rt/unittests/Runtime/NumericalFormatTest.cpp b/flang-rt/unittests/Runtime/NumericalFormatTest.cpp
index 5a8ead48dcef9..36170ea1056fd 100644
--- a/flang-rt/unittests/Runtime/NumericalFormatTest.cpp
+++ b/flang-rt/unittests/Runtime/NumericalFormatTest.cpp
@@ -8,7 +8,7 @@
#include "CrashHandlerFixture.h"
#include "flang-rt/runtime/descriptor.h"
-#include "flang/Runtime/io-api-consts.h"
+#include "flang/Runtime/io-api.h"
#include <algorithm>
#include <array>
#include <cstring>
diff --git a/flang-rt/unittests/Runtime/RuntimeCrashTest.cpp b/flang-rt/unittests/Runtime/RuntimeCrashTest.cpp
index e716dac2d1203..eaaf2a6e81b71 100644
--- a/flang-rt/unittests/Runtime/RuntimeCrashTest.cpp
+++ b/flang-rt/unittests/Runtime/RuntimeCrashTest.cpp
@@ -13,7 +13,7 @@
#include "CrashHandlerFixture.h"
#include "tools.h"
#include "flang-rt/runtime/terminator.h"
-#include "flang/Runtime/io-api-consts.h"
+#include "flang/Runtime/io-api.h"
#include "flang/Runtime/transformational.h"
#include <gtest/gtest.h>
diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md
index eb09d550504d0..7eb1805a6f01b 100644
--- a/flang/docs/Intrinsics.md
+++ b/flang/docs/Intrinsics.md
@@ -1096,6 +1096,41 @@ program chdir_func
end program chdir_func
```
+### Non-Standard Intrinsics: FSEEK and FTELL
+
+#### Description
+`FSEEK(UNIT, OFFSET, WHENCE)` Sets position in file opened as `UNIT`, returns status.
+
+`CALL FSEEK(UNIT, OFFSET, WHENCE[, STATUS])` Sets position, returns any error in `STATUS` if present.
+
+`FTELL(UNIT)` Returns current absolute byte offset.
+
+`CALL FTELL(UNIT, OFFSET)` Set `OFFSET` to current byte offset in file.
+
+These intrinsic procedures are available as both functions and subroutines,
+but both forms cannot be used in the same scope.
+
+| | |
+|------------|-------------------------------------------------|
+| `UNIT` | An open unit number |
+| `OFFSET` | A byte offset; set to -1 by `FTELL` on error |
+| `WHENCE` | 0: `OFFSET` is an absolute position |
+| | 1: `OFFSET` is relative to the current position |
+| | 2: `OFFSET` is relative to the end of the file |
+| `STATUS` | Set to a nonzero value if an error occurs |
+|------------|-------------------------------------------------|
+
+The aliases `FSEEK64`, `FSEEKO64`, `FSEEKI8`, `FTELL64`, `FTELLO64`, and
+`FTELLI8` are also accepted for further compatibility.
+
+Avoid using these intrinsics in new code when the standard `ACCESS="STREAM"`
+feature meets your needs.
+
+#### Usage and Info
+
+- **Standard:** Extensions to GNU, Intel, and SUN (at least)
+- **Class:** Subroutine, function
+
### Non-Standard Intrinsics: IERRNO
#### Description
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index 589a936f8b8c7..539e3a53b5be5 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -266,6 +266,10 @@ struct IntrinsicLibrary {
mlir::Value genFraction(mlir::Type resultType,
mlir::ArrayRef<mlir::Value> args);
void genFree(mlir::ArrayRef<fir::ExtendedValue> args);
+ fir::ExtendedValue genFseek(std::optional<mlir::Type>,
+ mlir::ArrayRef<fir::ExtendedValue> args);
+ fir::ExtendedValue genFtell(std::optional<mlir::Type>,
+ mlir::ArrayRef<fir::ExtendedValue> args);
fir::ExtendedValue genGetCwd(std::optional<mlir::Type> resultType,
llvm::ArrayRef<fir::ExtendedValue> args);
void genGetCommand(mlir::ArrayRef<fir::ExtendedValue> args);
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Intrinsics.h b/flang/include/flang/Optimizer/Builder/Runtime/Intrinsics.h
index 51d2dc82f98ae..4562134f4ecb5 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Intrinsics.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Intrinsics.h
@@ -49,6 +49,11 @@ void genEtime(fir::FirOpBuilder &builder, mlir::Location loc,
void genFree(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value ptr);
+mlir::Value genFseek(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value unit, mlir::Value offset, mlir::Value whence);
+mlir::Value genFtell(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value unit);
+
mlir::Value genGetUID(fir::FirOpBuilder &, mlir::Location);
mlir::Value genGetGID(fir::FirOpBuilder &, mlir::Location);
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
index 722e9191be728..a93c98f223839 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
@@ -21,7 +21,7 @@
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Dialect/FIRDialect.h"
#include "flang/Optimizer/Dialect/FIRType.h"
-#include "flang/Runtime/io-api-consts.h"
+#include "flang/Runtime/io-api.h"
#include "flang/Runtime/reduce.h"
#include "flang/Support/Fortran.h"
#include "mlir/IR/BuiltinTypes.h"
diff --git a/flang/include/flang/Runtime/extensions.h b/flang/include/flang/Runtime/extensions.h
index 133194dea87cf..b64c50ebfc887 100644
--- a/flang/include/flang/Runtime/extensions.h
+++ b/flang/include/flang/Runtime/extensions.h
@@ -38,6 +38,11 @@ void FORTRAN_PROCEDURE_NAME(fdate)(char *string, std::int64_t length);
void RTNAME(Free)(std::intptr_t ptr);
+// Common extensions FSEEK & FTELL, variously named
+std::int32_t RTNAME(Fseek)(int unit, std::int64_t zeroBasedPos, int whence,
+ const char *sourceFileName, int lineNumber);
+std::int64_t RTNAME(Ftell)(int unit);
+
// GNU Fortran 77 compatibility function IARGC.
std::int32_t FORTRAN_PROCEDURE_NAME(iargc)();
diff --git a/flang/include/flang/Runtime/io-api-consts.h b/flang/include/flang/Runtime/io-api-consts.h
deleted file mode 100644
index 7ed8bf1489b3c..0000000000000
--- a/flang/include/flang/Runtime/io-api-consts.h
+++ /dev/null
@@ -1,368 +0,0 @@
-//===-- include/flang/Runtime/io-api-consts.h -------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef FORTRAN_RUNTIME_IO_API_CONSTS_H_
-#define FORTRAN_RUNTIME_IO_API_CONSTS_H_
-
-#include "flang/Common/uint128.h"
-#include "flang/Runtime/entry-names.h"
-#include "flang/Runtime/iostat-consts.h"
-#include "flang/Runtime/magic-numbers.h"
-#include <cinttypes>
-#include <cstddef>
-
-namespace Fortran::runtime {
-class Descriptor;
-} // namespace Fortran::runtime
-
-namespace Fortran::runtime::io {
-
-struct NonTbpDefinedIoTable;
-class NamelistGroup;
-class IoStatementState;
-using Cookie = IoStatementState *;
-using ExternalUnit = int;
-using AsynchronousId = int;
-
-static constexpr ExternalUnit DefaultOutputUnit{FORTRAN_DEFAULT_OUTPUT_UNIT};
-static constexpr ExternalUnit DefaultInputUnit{FORTRAN_DEFAULT_INPUT_UNIT};
-
-// INQUIRE specifiers are encoded as simple base-26 packings of
-// the spellings of their keywords.
-using InquiryKeywordHash = std::uint64_t;
-constexpr InquiryKeywordHash HashInquiryKeyword(const char *p) {
- InquiryKeywordHash hash{1};
- while (char ch{*p++}) {
- std::uint64_t letter{0};
- if (ch >= 'a' && ch <= 'z') {
- letter = ch - 'a';
- } else {
- letter = ch - 'A';
- }
- hash = 26 * hash + letter;
- }
- return hash;
-}
-
-extern "C" {
-
-#define IONAME(name) RTNAME(io##name)
-
-#ifndef IODECL
-#define IODECL(name) RT_API_ATTRS IONAME(name)
-#endif
-
-#ifndef IODEF
-#define IODEF(name) RT_API_ATTRS IONAME(name)
-#endif
-
-// These functions initiate data transfer statements (READ, WRITE, PRINT).
-// Example: PRINT *, 666 is implemented as the series of calls:
-// Cookie cookie{BeginExternalListOutput(DefaultOutputUnit,
-// __FILE__, __LINE__)};
-// OutputInteger32(cookie, 666);
-// EndIoStatement(cookie);
-// Formatted I/O with explicit formats can supply the format as a
-// const char * pointer with a length, or with a descriptor.
-
-// Internal I/O initiation
-// Internal I/O can loan the runtime library an optional block of memory
-// in which the library can maintain state across the calls that implement
-// the internal transfer; use of these blocks can reduce the need for dynamic
-// memory allocation &/or thread-local storage. The block must be sufficiently
-// aligned to hold a pointer.
-constexpr std::size_t RecommendedInternalIoScratchAreaBytes(
- int maxFormatParenthesesNestingDepth) {
- return 32 + 8 * maxFormatParenthesesNestingDepth;
-}
-
-// For NAMELIST I/O, use the API for the appropriate form of list-directed
-// I/O initiation and configuration, then call OutputNamelist/InputNamelist
-// below.
-
-// Internal I/O to/from character arrays &/or non-default-kind character
-// requires a descriptor, which is copied.
-Cookie IODECL(BeginInternalArrayListOutput)(const Descriptor &,
- void **scratchArea = nullptr, std::size_t scratchBytes = 0,
- const char *sourceFile = nullptr, int sourceLine = 0);
-Cookie IODECL(BeginInternalArrayListInput)(const Descriptor &,
- void **scratchArea = nullptr, std::size_t scratchBytes = 0,
- const char *sourceFile = nullptr, int sourceLine = 0);
-Cookie IODECL(BeginInternalArrayFormattedOutput)(const Descriptor &,
- const char *format, std::size_t formatLength,
- const Descriptor *formatDescriptor = nullptr, void **scratchArea = nullptr,
- std::size_t scratchBytes = 0, const char *sourceFile = nullptr,
- int sourceLine = 0);
-Cookie IODECL(BeginInternalArrayFormattedInput)(const Descriptor &,
- const char *format, std::size_t formatLength,
- const Descriptor *formatDescriptor = nullptr, void **scratchArea = nullptr,
- std::size_t scratchBytes = 0, const char *sourceFile = nullptr,
- int sourceLine = 0);
-
-// Internal I/O to/from a default-kind character scalar can avoid a
-// descriptor.
-Cookie IODECL(BeginInternalListOutput)(char *internal,
- std::size_t internalLength, void **scratchArea = nullptr,
- std::size_t scratchBytes = 0, const char *sourceFile = nullptr,
- int sourceLine = 0);
-Co...
[truncated]
|
Once LLVM PR llvm/llvm-project#133003 merges, these tests can be enabled.
✅ With the latest revision this PR passed the C/C++ code formatter. |
c1bb2ae
to
7eba8ee
Compare
but both forms cannot be used in the same scope. | ||
|
||
These arguments must all be integers. | ||
The value returned from the function form of `FTELL` is `INTEGER(8)`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ok with it being INTEGER(8)
, but please note that both GNU and nvfortran documentation have it as default INTEGER.
{}, Rank::elemental, IntrinsicClass::impureSubroutine}, | ||
{"ftell", | ||
{{"unit", AnyInt, Rank::scalar}, | ||
{"offset", AnyInt, Rank::scalar, Optionality::required, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, if the function form of ftell()
returns INTEGER(8)
, shouldn't the subroutine form force the offset to be INTEGER(8)
as well? (With the caveat that GNU documentation has it as default INTEGER
.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've implemented it in a generic form that will work with any kind of integer variable that is associated with the dummy argument, which seemed to me to be the best for portability.
Once LLVM PR llvm/llvm-project#133003 merges, these tests can be enabled.
Add function and subroutine forms of FSEEK and FTELL as intrinsic procedures. Accept common aliases from legacy compilers as well. A separate patch to llvm-test-suite will enable tests for these procedures once this patch has merged. Depends on llvm#132423; CI builds will likely fail until that patch is merged and this PR is rebased.
Once LLVM PR llvm/llvm-project#133003 merges, these tests can be enabled.
Add function and subroutine forms of FSEEK and FTELL as intrinsic procedures. Accept common aliases from legacy compilers as well.
A separate patch to llvm-test-suite will enable tests for these procedures once this patch has merged.
Depends on #132423; CI builds will likely fail until that patch is merged and this PR is rebased.