Skip to content

[flang][NFC] Restore I/O runtime API header name #132423

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

Merged
merged 1 commit into from
Mar 26, 2025
Merged

Conversation

klausler
Copy link
Contributor

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.

@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir labels Mar 21, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 21, 2025

@llvm/pr-subscribers-flang-fir-hlfir

Author: Peter Klausler (klausler)

Changes

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.


Patch is 36.53 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/132423.diff

6 Files Affected:

  • (modified) flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h (+1-1)
  • (removed) flang/include/flang/Runtime/io-api-consts.h (-368)
  • (modified) flang/include/flang/Runtime/io-api.h (+336-5)
  • (modified) flang/lib/Lower/IO.cpp (+1-1)
  • (modified) flang/lib/Optimizer/Transforms/GenRuntimeCallsForTest.cpp (+1-1)
  • (modified) flang/lib/Optimizer/Transforms/SetRuntimeCallAttributes.cpp (+1-1)
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/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);
-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_ */
diff --git a/flang/include/flang/Runtime/io-api.h b/flang/include/flang/Runtime/io-api.h
index b86c3cecb32c5..988fe536705e6 100644
--- a/flang/include/flang/Runtime/io-api.h
+++ b/flang/include/flang/Runtime/io-api.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
+/...
[truncated]

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.
Copy link
Member

@Meinersbur Meinersbur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, altough I think inline should be avoided for larger functions to reduce compile time and I don't see how it could cause confusion. If header name confusion is an issue, the bigger issue is that we have many headers with the same name. We have four different Allocatable.h/allocatable.h, five tools.h and five Utils.h.

klausler added a commit to klausler/llvm-project that referenced this pull request Mar 25, 2025
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.
klausler added a commit to klausler/llvm-project that referenced this pull request Mar 25, 2025
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.
@klausler klausler merged commit 4ea5aa0 into llvm:main Mar 26, 2025
11 checks passed
@klausler klausler deleted the io-api branch March 26, 2025 19:09
klausler added a commit to klausler/llvm-project that referenced this pull request Mar 26, 2025
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.
klausler added a commit to klausler/llvm-project that referenced this pull request Mar 26, 2025
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.
klausler added a commit to klausler/llvm-project that referenced this pull request Mar 27, 2025
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.
klausler added a commit to klausler/llvm-project that referenced this pull request Mar 27, 2025
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.
klausler added a commit to klausler/llvm-project that referenced this pull request Apr 4, 2025
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.
klausler added a commit to klausler/llvm-project that referenced this pull request Apr 4, 2025
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.
klausler added a commit that referenced this pull request Apr 4, 2025
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.
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Apr 4, 2025
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/llvm-project#132423; CI builds
will likely fail until that patch is merged and this PR is rebased.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:fir-hlfir flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants