mirror of
https://github.com/intel/llvm.git
synced 2026-01-27 06:06:34 +08:00
[flang][NFC] Restore I/O runtime API header name (#132423)
flang/include/flang/Runtime/io-api.h was changed into io-api-consts.h, then wrapped into a new io-api.h that includes io-api-consts.h, does some redundant includes and declarations, and then declares the prototype of one function, InquiryKeywordHashDecode. Make that function static in io-stmt.cpp prior to its sole call site, then undo the renaming, to reduce confusion and redundancy.
This commit is contained in:
@@ -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*/,
|
||||
|
||||
@@ -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)};
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
Cookie IODECL(BeginInternalListInput)(const char *internal,
|
||||
std::size_t internalLength, void **scratchArea = nullptr,
|
||||
std::size_t scratchBytes = 0, const char *sourceFile = nullptr,
|
||||
int sourceLine = 0);
|
||||
Cookie IODECL(BeginInternalFormattedOutput)(char *internal,
|
||||
std::size_t internalLength, 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(BeginInternalFormattedInput)(const char *internal,
|
||||
std::size_t internalLength, 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);
|
||||
|
||||
// External unit numbers must fit in default integers. When the integer
|
||||
// provided as UNIT is of a wider type than the default integer, it could
|
||||
// overflow when converted to a default integer.
|
||||
// CheckUnitNumberInRange should be called to verify that a unit number of a
|
||||
// wide integer type can fit in a default integer. Since it should be called
|
||||
// before the BeginXXX(unit, ...) call, it has its own error handling interface.
|
||||
// If handleError is false, and the unit number is out of range, the program
|
||||
// will be terminated. Otherwise, if unit is out of range, a nonzero Iostat
|
||||
// code is returned and ioMsg is set if it is not a nullptr.
|
||||
enum Iostat IODECL(CheckUnitNumberInRange64)(std::int64_t unit,
|
||||
bool handleError, char *ioMsg = nullptr, std::size_t ioMsgLength = 0,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
enum Iostat IODECL(CheckUnitNumberInRange128)(common::int128_t unit,
|
||||
bool handleError, char *ioMsg = nullptr, std::size_t ioMsgLength = 0,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
|
||||
// External synchronous I/O initiation
|
||||
Cookie IODECL(BeginExternalListOutput)(ExternalUnit = DefaultOutputUnit,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginExternalListInput)(ExternalUnit = DefaultInputUnit,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginExternalFormattedOutput)(const char *format, std::size_t,
|
||||
const Descriptor *formatDescriptor = nullptr,
|
||||
ExternalUnit = DefaultOutputUnit, const char *sourceFile = nullptr,
|
||||
int sourceLine = 0);
|
||||
Cookie IODECL(BeginExternalFormattedInput)(const char *format, std::size_t,
|
||||
const Descriptor *formatDescriptor = nullptr,
|
||||
ExternalUnit = DefaultInputUnit, const char *sourceFile = nullptr,
|
||||
int sourceLine = 0);
|
||||
Cookie IODECL(BeginUnformattedOutput)(ExternalUnit = DefaultOutputUnit,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginUnformattedInput)(ExternalUnit = DefaultInputUnit,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
|
||||
// WAIT(ID=)
|
||||
Cookie IODECL(BeginWait)(ExternalUnit, AsynchronousId,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
// WAIT(no ID=)
|
||||
Cookie IODECL(BeginWaitAll)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
|
||||
// Other I/O statements
|
||||
Cookie IODECL(BeginClose)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginFlush)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginBackspace)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginEndfile)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginRewind)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
|
||||
// OPEN(UNIT=) and OPEN(NEWUNIT=) have distinct interfaces.
|
||||
Cookie IODECL(BeginOpenUnit)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginOpenNewUnit)(
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
|
||||
// The variant forms of INQUIRE() statements have distinct interfaces.
|
||||
// BeginInquireIoLength() is basically a no-op output statement.
|
||||
Cookie IODECL(BeginInquireUnit)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginInquireFile)(const char *, std::size_t,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginInquireIoLength)(
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
|
||||
// If an I/O statement has any IOSTAT=, ERR=, END=, or EOR= specifiers,
|
||||
// call EnableHandlers() immediately after the Begin...() call.
|
||||
// An output or OPEN statement may not enable HasEnd or HasEor.
|
||||
// This call makes the runtime library defer those particular error/end
|
||||
// conditions to the EndIoStatement() call rather than terminating
|
||||
// the image. E.g., for READ(*,*,END=666) A, B, (C(J),J=1,N)
|
||||
// Cookie cookie{BeginExternalListInput(DefaultInputUnit,__FILE__,__LINE__)};
|
||||
// EnableHandlers(cookie, false, false, true /*END=*/, false);
|
||||
// if (InputReal64(cookie, &A)) {
|
||||
// if (InputReal64(cookie, &B)) {
|
||||
// for (int J{1}; J<=N; ++J) {
|
||||
// if (!InputReal64(cookie, &C[J])) break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (EndIoStatement(cookie) == FORTRAN_RUTIME_IOSTAT_END) goto label666;
|
||||
void IODECL(EnableHandlers)(Cookie, bool hasIoStat = false, bool hasErr = false,
|
||||
bool hasEnd = false, bool hasEor = false, bool hasIoMsg = false);
|
||||
|
||||
// ASYNCHRONOUS='YES' or 'NO' on READ/WRITE/OPEN
|
||||
// Use GetAsynchronousId() to handle ID=.
|
||||
bool IODECL(SetAsynchronous)(Cookie, const char *, std::size_t);
|
||||
|
||||
// Control list options. These return false on a error that the
|
||||
// Begin...() call has specified will be handled by the caller.
|
||||
// The interfaces that pass a default-kind CHARACTER argument
|
||||
// are limited to passing specific case-insensitive keyword values.
|
||||
// ADVANCE=YES, NO
|
||||
bool IODECL(SetAdvance)(Cookie, const char *, std::size_t);
|
||||
// BLANK=NULL, ZERO
|
||||
bool IODECL(SetBlank)(Cookie, const char *, std::size_t);
|
||||
// DECIMAL=COMMA, POINT
|
||||
bool IODECL(SetDecimal)(Cookie, const char *, std::size_t);
|
||||
// DELIM=APOSTROPHE, QUOTE, NONE
|
||||
bool IODECL(SetDelim)(Cookie, const char *, std::size_t);
|
||||
// PAD=YES, NO
|
||||
bool IODECL(SetPad)(Cookie, const char *, std::size_t);
|
||||
bool IODECL(SetPos)(Cookie, std::int64_t);
|
||||
bool IODECL(SetRec)(Cookie, std::int64_t);
|
||||
// ROUND=UP, DOWN, ZERO, NEAREST, COMPATIBLE, PROCESSOR_DEFINED
|
||||
bool IODECL(SetRound)(Cookie, const char *, std::size_t);
|
||||
// SIGN=PLUS, SUPPRESS, PROCESSOR_DEFINED
|
||||
bool IODECL(SetSign)(Cookie, const char *, std::size_t);
|
||||
|
||||
// Data item transfer for modes other than NAMELIST:
|
||||
// Any data object that can be passed as an actual argument without the
|
||||
// use of a temporary can be transferred by means of a descriptor;
|
||||
// vector-valued subscripts and coindexing will require elementwise
|
||||
// transfers &/or data copies. Unformatted transfers to/from contiguous
|
||||
// blocks of local image memory can avoid the descriptor, and there
|
||||
// are specializations for the most common scalar types.
|
||||
//
|
||||
// These functions return false when the I/O statement has encountered an
|
||||
// error or end-of-file/record condition that the caller has indicated
|
||||
// should not cause termination of the image by the runtime library.
|
||||
// Once the statement has encountered an error, all following items will be
|
||||
// ignored and also return false; but compiled code should check for errors
|
||||
// and avoid the following items when they might crash.
|
||||
bool IODECL(OutputDescriptor)(Cookie, const Descriptor &);
|
||||
bool IODECL(InputDescriptor)(Cookie, const Descriptor &);
|
||||
// Formatted (including list directed) I/O data items
|
||||
bool IODECL(OutputInteger8)(Cookie, std::int8_t);
|
||||
bool IODECL(OutputInteger16)(Cookie, std::int16_t);
|
||||
bool IODECL(OutputInteger32)(Cookie, std::int32_t);
|
||||
bool IODECL(OutputInteger64)(Cookie, std::int64_t);
|
||||
bool IODECL(OutputInteger128)(Cookie, common::int128_t);
|
||||
bool IODECL(InputInteger)(Cookie, std::int64_t &, int kind = 8);
|
||||
bool IODECL(OutputReal32)(Cookie, float);
|
||||
bool IODECL(InputReal32)(Cookie, float &);
|
||||
bool IODECL(OutputReal64)(Cookie, double);
|
||||
bool IODECL(InputReal64)(Cookie, double &);
|
||||
bool IODECL(OutputComplex32)(Cookie, float, float);
|
||||
bool IODECL(InputComplex32)(Cookie, float[2]);
|
||||
bool IODECL(OutputComplex64)(Cookie, double, double);
|
||||
bool IODECL(InputComplex64)(Cookie, double[2]);
|
||||
bool IODECL(OutputCharacter)(Cookie, const char *, std::size_t, int kind = 1);
|
||||
bool IODECL(OutputAscii)(Cookie, const char *, std::size_t);
|
||||
bool IODECL(InputCharacter)(Cookie, char *, std::size_t, int kind = 1);
|
||||
bool IODECL(InputAscii)(Cookie, char *, std::size_t);
|
||||
bool IODECL(OutputLogical)(Cookie, bool);
|
||||
bool IODECL(InputLogical)(Cookie, bool &);
|
||||
|
||||
// NAMELIST I/O must be the only data item in an (otherwise)
|
||||
// list-directed I/O statement.
|
||||
bool IODECL(OutputNamelist)(Cookie, const NamelistGroup &);
|
||||
bool IODECL(InputNamelist)(Cookie, const NamelistGroup &);
|
||||
|
||||
// When an I/O list item has a derived type with a specific defined
|
||||
// I/O subroutine of the appropriate generic kind for the active
|
||||
// I/O data transfer statement (read/write, formatted/unformatted)
|
||||
// that pertains to the type or its components, and those subroutines
|
||||
// are dynamic or neither type-bound nor defined with interfaces
|
||||
// in the same scope as the derived type (or an IMPORT statement has
|
||||
// made such a generic interface inaccessible), these data item transfer
|
||||
// APIs enable the I/O runtime to make the right calls to defined I/O
|
||||
// subroutines.
|
||||
bool IODECL(OutputDerivedType)(
|
||||
Cookie, const Descriptor &, const NonTbpDefinedIoTable *);
|
||||
bool IODECL(InputDerivedType)(
|
||||
Cookie, const Descriptor &, const NonTbpDefinedIoTable *);
|
||||
|
||||
// Additional specifier interfaces for the connection-list of
|
||||
// on OPEN statement (only). SetBlank(), SetDecimal(),
|
||||
// SetDelim(), GetIoMsg(), SetPad(), SetRound(), SetSign(),
|
||||
// & SetAsynchronous() are also acceptable for OPEN.
|
||||
// ACCESS=SEQUENTIAL, DIRECT, STREAM
|
||||
bool IODECL(SetAccess)(Cookie, const char *, std::size_t);
|
||||
// ACTION=READ, WRITE, or READWRITE
|
||||
bool IODECL(SetAction)(Cookie, const char *, std::size_t);
|
||||
// CARRIAGECONTROL=LIST, FORTRAN, NONE
|
||||
bool IODECL(SetCarriagecontrol)(Cookie, const char *, std::size_t);
|
||||
// CONVERT=NATIVE, LITTLE_ENDIAN, BIG_ENDIAN, or SWAP
|
||||
bool IODECL(SetConvert)(Cookie, const char *, std::size_t);
|
||||
// ENCODING=UTF-8, DEFAULT
|
||||
bool IODECL(SetEncoding)(Cookie, const char *, std::size_t);
|
||||
// FORM=FORMATTED, UNFORMATTED
|
||||
bool IODECL(SetForm)(Cookie, const char *, std::size_t);
|
||||
// POSITION=ASIS, REWIND, APPEND
|
||||
bool IODECL(SetPosition)(Cookie, const char *, std::size_t);
|
||||
bool IODECL(SetRecl)(Cookie, std::size_t); // RECL=
|
||||
|
||||
// STATUS can be set during an OPEN or CLOSE statement.
|
||||
// For OPEN: STATUS=OLD, NEW, SCRATCH, REPLACE, UNKNOWN
|
||||
// For CLOSE: STATUS=KEEP, DELETE
|
||||
bool IODECL(SetStatus)(Cookie, const char *, std::size_t);
|
||||
|
||||
bool IODECL(SetFile)(Cookie, const char *, std::size_t chars);
|
||||
|
||||
// Acquires the runtime-created unit number for OPEN(NEWUNIT=)
|
||||
bool IODECL(GetNewUnit)(Cookie, int &, int kind = 4);
|
||||
|
||||
// READ(SIZE=), after all input items
|
||||
std::size_t IODECL(GetSize)(Cookie);
|
||||
|
||||
// INQUIRE(IOLENGTH=), after all output items
|
||||
std::size_t IODECL(GetIoLength)(Cookie);
|
||||
|
||||
// GetIoMsg() does not modify its argument unless an error or
|
||||
// end-of-record/file condition is present.
|
||||
void IODECL(GetIoMsg)(Cookie, char *, std::size_t); // IOMSG=
|
||||
|
||||
// Defines ID= on READ/WRITE(ASYNCHRONOUS='YES')
|
||||
AsynchronousId IODECL(GetAsynchronousId)(Cookie);
|
||||
|
||||
// INQUIRE() specifiers are mostly identified by their NUL-terminated
|
||||
// case-insensitive names.
|
||||
// ACCESS, ACTION, ASYNCHRONOUS, BLANK, CONVERT, DECIMAL, DELIM, DIRECT,
|
||||
// ENCODING, FORM, FORMATTED, NAME, PAD, POSITION, READ, READWRITE, ROUND,
|
||||
// SEQUENTIAL, SIGN, STREAM, UNFORMATTED, WRITE:
|
||||
bool IODECL(InquireCharacter)(Cookie, InquiryKeywordHash, char *, std::size_t);
|
||||
// EXIST, NAMED, OPENED, and PENDING (without ID):
|
||||
bool IODECL(InquireLogical)(Cookie, InquiryKeywordHash, bool &);
|
||||
// PENDING with ID
|
||||
bool IODECL(InquirePendingId)(Cookie, AsynchronousId, bool &);
|
||||
// NEXTREC, NUMBER, POS, RECL, SIZE
|
||||
bool IODECL(InquireInteger64)(
|
||||
Cookie, InquiryKeywordHash, std::int64_t &, int kind = 8);
|
||||
|
||||
// This function must be called to end an I/O statement, and its
|
||||
// cookie value may not be used afterwards unless it is recycled
|
||||
// by the runtime library to serve a later I/O statement.
|
||||
// The return value can be used to implement IOSTAT=, ERR=, END=, & EOR=;
|
||||
// store it into the IOSTAT= variable if there is one, and test
|
||||
// it to implement the various branches. The error condition
|
||||
// returned is guaranteed to only be one of the problems that the
|
||||
// EnableHandlers() call has indicated should be handled in compiled code
|
||||
// rather than by terminating the image.
|
||||
enum Iostat IODECL(EndIoStatement)(Cookie);
|
||||
|
||||
} // extern "C"
|
||||
} // namespace Fortran::runtime::io
|
||||
|
||||
#endif /* FORTRAN_RUNTIME_IO_API_CONSTS_H_ */
|
||||
@@ -6,14 +6,13 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Defines API between compiled code and I/O runtime library.
|
||||
// Defines the API of the I/O runtime support library for lowering.
|
||||
|
||||
#ifndef FORTRAN_RUNTIME_IO_API_H_
|
||||
#define FORTRAN_RUNTIME_IO_API_H_
|
||||
|
||||
#include "flang/Common/uint128.h"
|
||||
#include "flang/Runtime/entry-names.h"
|
||||
#include "flang/Runtime/io-api-consts.h"
|
||||
#include "flang/Runtime/iostat-consts.h"
|
||||
#include "flang/Runtime/magic-numbers.h"
|
||||
#include <cinttypes>
|
||||
@@ -32,8 +31,340 @@ using Cookie = IoStatementState *;
|
||||
using ExternalUnit = int;
|
||||
using AsynchronousId = int;
|
||||
|
||||
RT_API_ATTRS const char *InquiryKeywordHashDecode(
|
||||
char *buffer, std::size_t, InquiryKeywordHash);
|
||||
static constexpr ExternalUnit DefaultOutputUnit{FORTRAN_DEFAULT_OUTPUT_UNIT};
|
||||
static constexpr ExternalUnit DefaultInputUnit{FORTRAN_DEFAULT_INPUT_UNIT};
|
||||
|
||||
} // namespace Fortran::runtime::io
|
||||
// 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);
|
||||
Cookie IODECL(BeginInternalListInput)(const char *internal,
|
||||
std::size_t internalLength, void **scratchArea = nullptr,
|
||||
std::size_t scratchBytes = 0, const char *sourceFile = nullptr,
|
||||
int sourceLine = 0);
|
||||
Cookie IODECL(BeginInternalFormattedOutput)(char *internal,
|
||||
std::size_t internalLength, 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(BeginInternalFormattedInput)(const char *internal,
|
||||
std::size_t internalLength, 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);
|
||||
|
||||
// External unit numbers must fit in default integers. When the integer
|
||||
// provided as UNIT is of a wider type than the default integer, it could
|
||||
// overflow when converted to a default integer.
|
||||
// CheckUnitNumberInRange should be called to verify that a unit number of a
|
||||
// wide integer type can fit in a default integer. Since it should be called
|
||||
// before the BeginXXX(unit, ...) call, it has its own error handling interface.
|
||||
// If handleError is false, and the unit number is out of range, the program
|
||||
// will be terminated. Otherwise, if unit is out of range, a nonzero Iostat
|
||||
// code is returned and ioMsg is set if it is not a nullptr.
|
||||
enum Iostat IODECL(CheckUnitNumberInRange64)(std::int64_t unit,
|
||||
bool handleError, char *ioMsg = nullptr, std::size_t ioMsgLength = 0,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
enum Iostat IODECL(CheckUnitNumberInRange128)(common::int128_t unit,
|
||||
bool handleError, char *ioMsg = nullptr, std::size_t ioMsgLength = 0,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
|
||||
// External synchronous I/O initiation
|
||||
Cookie IODECL(BeginExternalListOutput)(ExternalUnit = DefaultOutputUnit,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginExternalListInput)(ExternalUnit = DefaultInputUnit,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginExternalFormattedOutput)(const char *format, std::size_t,
|
||||
const Descriptor *formatDescriptor = nullptr,
|
||||
ExternalUnit = DefaultOutputUnit, const char *sourceFile = nullptr,
|
||||
int sourceLine = 0);
|
||||
Cookie IODECL(BeginExternalFormattedInput)(const char *format, std::size_t,
|
||||
const Descriptor *formatDescriptor = nullptr,
|
||||
ExternalUnit = DefaultInputUnit, const char *sourceFile = nullptr,
|
||||
int sourceLine = 0);
|
||||
Cookie IODECL(BeginUnformattedOutput)(ExternalUnit = DefaultOutputUnit,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginUnformattedInput)(ExternalUnit = DefaultInputUnit,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
|
||||
// WAIT(ID=)
|
||||
Cookie IODECL(BeginWait)(ExternalUnit, AsynchronousId,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
// WAIT(no ID=)
|
||||
Cookie IODECL(BeginWaitAll)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
|
||||
// Other I/O statements
|
||||
Cookie IODECL(BeginClose)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginFlush)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginBackspace)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginEndfile)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginRewind)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
|
||||
// OPEN(UNIT=) and OPEN(NEWUNIT=) have distinct interfaces.
|
||||
Cookie IODECL(BeginOpenUnit)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginOpenNewUnit)(
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
|
||||
// The variant forms of INQUIRE() statements have distinct interfaces.
|
||||
// BeginInquireIoLength() is basically a no-op output statement.
|
||||
Cookie IODECL(BeginInquireUnit)(
|
||||
ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginInquireFile)(const char *, std::size_t,
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
Cookie IODECL(BeginInquireIoLength)(
|
||||
const char *sourceFile = nullptr, int sourceLine = 0);
|
||||
|
||||
// If an I/O statement has any IOSTAT=, ERR=, END=, or EOR= specifiers,
|
||||
// call EnableHandlers() immediately after the Begin...() call.
|
||||
// An output or OPEN statement may not enable HasEnd or HasEor.
|
||||
// This call makes the runtime library defer those particular error/end
|
||||
// conditions to the EndIoStatement() call rather than terminating
|
||||
// the image. E.g., for READ(*,*,END=666) A, B, (C(J),J=1,N)
|
||||
// Cookie cookie{BeginExternalListInput(DefaultInputUnit,__FILE__,__LINE__)};
|
||||
// EnableHandlers(cookie, false, false, true /*END=*/, false);
|
||||
// if (InputReal64(cookie, &A)) {
|
||||
// if (InputReal64(cookie, &B)) {
|
||||
// for (int J{1}; J<=N; ++J) {
|
||||
// if (!InputReal64(cookie, &C[J])) break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if (EndIoStatement(cookie) == FORTRAN_RUTIME_IOSTAT_END) goto label666;
|
||||
void IODECL(EnableHandlers)(Cookie, bool hasIoStat = false, bool hasErr = false,
|
||||
bool hasEnd = false, bool hasEor = false, bool hasIoMsg = false);
|
||||
|
||||
// ASYNCHRONOUS='YES' or 'NO' on READ/WRITE/OPEN
|
||||
// Use GetAsynchronousId() to handle ID=.
|
||||
bool IODECL(SetAsynchronous)(Cookie, const char *, std::size_t);
|
||||
|
||||
// Control list options. These return false on a error that the
|
||||
// Begin...() call has specified will be handled by the caller.
|
||||
// The interfaces that pass a default-kind CHARACTER argument
|
||||
// are limited to passing specific case-insensitive keyword values.
|
||||
// ADVANCE=YES, NO
|
||||
bool IODECL(SetAdvance)(Cookie, const char *, std::size_t);
|
||||
// BLANK=NULL, ZERO
|
||||
bool IODECL(SetBlank)(Cookie, const char *, std::size_t);
|
||||
// DECIMAL=COMMA, POINT
|
||||
bool IODECL(SetDecimal)(Cookie, const char *, std::size_t);
|
||||
// DELIM=APOSTROPHE, QUOTE, NONE
|
||||
bool IODECL(SetDelim)(Cookie, const char *, std::size_t);
|
||||
// PAD=YES, NO
|
||||
bool IODECL(SetPad)(Cookie, const char *, std::size_t);
|
||||
bool IODECL(SetPos)(Cookie, std::int64_t);
|
||||
bool IODECL(SetRec)(Cookie, std::int64_t);
|
||||
// ROUND=UP, DOWN, ZERO, NEAREST, COMPATIBLE, PROCESSOR_DEFINED
|
||||
bool IODECL(SetRound)(Cookie, const char *, std::size_t);
|
||||
// SIGN=PLUS, SUPPRESS, PROCESSOR_DEFINED
|
||||
bool IODECL(SetSign)(Cookie, const char *, std::size_t);
|
||||
|
||||
// Data item transfer for modes other than NAMELIST:
|
||||
// Any data object that can be passed as an actual argument without the
|
||||
// use of a temporary can be transferred by means of a descriptor;
|
||||
// vector-valued subscripts and coindexing will require elementwise
|
||||
// transfers &/or data copies. Unformatted transfers to/from contiguous
|
||||
// blocks of local image memory can avoid the descriptor, and there
|
||||
// are specializations for the most common scalar types.
|
||||
//
|
||||
// These functions return false when the I/O statement has encountered an
|
||||
// error or end-of-file/record condition that the caller has indicated
|
||||
// should not cause termination of the image by the runtime library.
|
||||
// Once the statement has encountered an error, all following items will be
|
||||
// ignored and also return false; but compiled code should check for errors
|
||||
// and avoid the following items when they might crash.
|
||||
bool IODECL(OutputDescriptor)(Cookie, const Descriptor &);
|
||||
bool IODECL(InputDescriptor)(Cookie, const Descriptor &);
|
||||
// Formatted (including list directed) I/O data items
|
||||
bool IODECL(OutputInteger8)(Cookie, std::int8_t);
|
||||
bool IODECL(OutputInteger16)(Cookie, std::int16_t);
|
||||
bool IODECL(OutputInteger32)(Cookie, std::int32_t);
|
||||
bool IODECL(OutputInteger64)(Cookie, std::int64_t);
|
||||
bool IODECL(OutputInteger128)(Cookie, common::int128_t);
|
||||
bool IODECL(InputInteger)(Cookie, std::int64_t &, int kind = 8);
|
||||
bool IODECL(OutputReal32)(Cookie, float);
|
||||
bool IODECL(InputReal32)(Cookie, float &);
|
||||
bool IODECL(OutputReal64)(Cookie, double);
|
||||
bool IODECL(InputReal64)(Cookie, double &);
|
||||
bool IODECL(OutputComplex32)(Cookie, float, float);
|
||||
bool IODECL(InputComplex32)(Cookie, float[2]);
|
||||
bool IODECL(OutputComplex64)(Cookie, double, double);
|
||||
bool IODECL(InputComplex64)(Cookie, double[2]);
|
||||
bool IODECL(OutputCharacter)(Cookie, const char *, std::size_t, int kind = 1);
|
||||
bool IODECL(OutputAscii)(Cookie, const char *, std::size_t);
|
||||
bool IODECL(InputCharacter)(Cookie, char *, std::size_t, int kind = 1);
|
||||
bool IODECL(InputAscii)(Cookie, char *, std::size_t);
|
||||
bool IODECL(OutputLogical)(Cookie, bool);
|
||||
bool IODECL(InputLogical)(Cookie, bool &);
|
||||
|
||||
// NAMELIST I/O must be the only data item in an (otherwise)
|
||||
// list-directed I/O statement.
|
||||
bool IODECL(OutputNamelist)(Cookie, const NamelistGroup &);
|
||||
bool IODECL(InputNamelist)(Cookie, const NamelistGroup &);
|
||||
|
||||
// When an I/O list item has a derived type with a specific defined
|
||||
// I/O subroutine of the appropriate generic kind for the active
|
||||
// I/O data transfer statement (read/write, formatted/unformatted)
|
||||
// that pertains to the type or its components, and those subroutines
|
||||
// are dynamic or neither type-bound nor defined with interfaces
|
||||
// in the same scope as the derived type (or an IMPORT statement has
|
||||
// made such a generic interface inaccessible), these data item transfer
|
||||
// APIs enable the I/O runtime to make the right calls to defined I/O
|
||||
// subroutines.
|
||||
bool IODECL(OutputDerivedType)(
|
||||
Cookie, const Descriptor &, const NonTbpDefinedIoTable *);
|
||||
bool IODECL(InputDerivedType)(
|
||||
Cookie, const Descriptor &, const NonTbpDefinedIoTable *);
|
||||
|
||||
// Additional specifier interfaces for the connection-list of
|
||||
// on OPEN statement (only). SetBlank(), SetDecimal(),
|
||||
// SetDelim(), GetIoMsg(), SetPad(), SetRound(), SetSign(),
|
||||
// & SetAsynchronous() are also acceptable for OPEN.
|
||||
// ACCESS=SEQUENTIAL, DIRECT, STREAM
|
||||
bool IODECL(SetAccess)(Cookie, const char *, std::size_t);
|
||||
// ACTION=READ, WRITE, or READWRITE
|
||||
bool IODECL(SetAction)(Cookie, const char *, std::size_t);
|
||||
// CARRIAGECONTROL=LIST, FORTRAN, NONE
|
||||
bool IODECL(SetCarriagecontrol)(Cookie, const char *, std::size_t);
|
||||
// CONVERT=NATIVE, LITTLE_ENDIAN, BIG_ENDIAN, or SWAP
|
||||
bool IODECL(SetConvert)(Cookie, const char *, std::size_t);
|
||||
// ENCODING=UTF-8, DEFAULT
|
||||
bool IODECL(SetEncoding)(Cookie, const char *, std::size_t);
|
||||
// FORM=FORMATTED, UNFORMATTED
|
||||
bool IODECL(SetForm)(Cookie, const char *, std::size_t);
|
||||
// POSITION=ASIS, REWIND, APPEND
|
||||
bool IODECL(SetPosition)(Cookie, const char *, std::size_t);
|
||||
bool IODECL(SetRecl)(Cookie, std::size_t); // RECL=
|
||||
|
||||
// STATUS can be set during an OPEN or CLOSE statement.
|
||||
// For OPEN: STATUS=OLD, NEW, SCRATCH, REPLACE, UNKNOWN
|
||||
// For CLOSE: STATUS=KEEP, DELETE
|
||||
bool IODECL(SetStatus)(Cookie, const char *, std::size_t);
|
||||
|
||||
bool IODECL(SetFile)(Cookie, const char *, std::size_t chars);
|
||||
|
||||
// Acquires the runtime-created unit number for OPEN(NEWUNIT=)
|
||||
bool IODECL(GetNewUnit)(Cookie, int &, int kind = 4);
|
||||
|
||||
// READ(SIZE=), after all input items
|
||||
std::size_t IODECL(GetSize)(Cookie);
|
||||
|
||||
// INQUIRE(IOLENGTH=), after all output items
|
||||
std::size_t IODECL(GetIoLength)(Cookie);
|
||||
|
||||
// GetIoMsg() does not modify its argument unless an error or
|
||||
// end-of-record/file condition is present.
|
||||
void IODECL(GetIoMsg)(Cookie, char *, std::size_t); // IOMSG=
|
||||
|
||||
// Defines ID= on READ/WRITE(ASYNCHRONOUS='YES')
|
||||
AsynchronousId IODECL(GetAsynchronousId)(Cookie);
|
||||
|
||||
// INQUIRE() specifiers are mostly identified by their NUL-terminated
|
||||
// case-insensitive names.
|
||||
// ACCESS, ACTION, ASYNCHRONOUS, BLANK, CONVERT, DECIMAL, DELIM, DIRECT,
|
||||
// ENCODING, FORM, FORMATTED, NAME, PAD, POSITION, READ, READWRITE, ROUND,
|
||||
// SEQUENTIAL, SIGN, STREAM, UNFORMATTED, WRITE:
|
||||
bool IODECL(InquireCharacter)(Cookie, InquiryKeywordHash, char *, std::size_t);
|
||||
// EXIST, NAMED, OPENED, and PENDING (without ID):
|
||||
bool IODECL(InquireLogical)(Cookie, InquiryKeywordHash, bool &);
|
||||
// PENDING with ID
|
||||
bool IODECL(InquirePendingId)(Cookie, AsynchronousId, bool &);
|
||||
// NEXTREC, NUMBER, POS, RECL, SIZE
|
||||
bool IODECL(InquireInteger64)(
|
||||
Cookie, InquiryKeywordHash, std::int64_t &, int kind = 8);
|
||||
|
||||
// This function must be called to end an I/O statement, and its
|
||||
// cookie value may not be used afterwards unless it is recycled
|
||||
// by the runtime library to serve a later I/O statement.
|
||||
// The return value can be used to implement IOSTAT=, ERR=, END=, & EOR=;
|
||||
// store it into the IOSTAT= variable if there is one, and test
|
||||
// it to implement the various branches. The error condition
|
||||
// returned is guaranteed to only be one of the problems that the
|
||||
// EnableHandlers() call has indicated should be handled in compiled code
|
||||
// rather than by terminating the image.
|
||||
enum Iostat IODECL(EndIoStatement)(Cookie);
|
||||
|
||||
} // extern "C"
|
||||
} // namespace Fortran::runtime::io
|
||||
|
||||
#endif /* FORTRAN_RUNTIME_IO_API_H_ */
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
|
||||
#include "flang/Optimizer/Support/InternalNames.h"
|
||||
#include "flang/Parser/parse-tree.h"
|
||||
#include "flang/Runtime/io-api-consts.h"
|
||||
#include "flang/Runtime/io-api.h"
|
||||
#include "flang/Semantics/runtime-type-info.h"
|
||||
#include "flang/Semantics/tools.h"
|
||||
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
|
||||
#include "flang/Optimizer/Support/InternalNames.h"
|
||||
#include "flang/Optimizer/Transforms/Passes.h"
|
||||
#include "flang/Runtime/io-api-consts.h"
|
||||
#include "flang/Runtime/io-api.h"
|
||||
#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
|
||||
|
||||
namespace fir {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
|
||||
#include "flang/Optimizer/Support/InternalNames.h"
|
||||
#include "flang/Optimizer/Transforms/Passes.h"
|
||||
#include "flang/Runtime/io-api-consts.h"
|
||||
#include "flang/Runtime/io-api.h"
|
||||
#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
|
||||
|
||||
namespace fir {
|
||||
|
||||
Reference in New Issue
Block a user