[Support] Remove unused includes (NFC) (#116752)
[llvm-project.git] / flang / runtime / io-api-minimal.cpp
blobad76fe3de0324c10df718c33097179a758f6778b
1 //===-- runtime/io-api-minimal.cpp ----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 // Implements the subset of the I/O statement API needed for basic
10 // list-directed output (PRINT *) of intrinsic types.
12 #include "edit-output.h"
13 #include "format.h"
14 #include "io-api-common.h"
15 #include "io-stmt.h"
16 #include "terminator.h"
17 #include "tools.h"
18 #include "unit.h"
19 #include "flang/Runtime/io-api.h"
21 namespace Fortran::runtime::io {
22 RT_EXT_API_GROUP_BEGIN
24 Cookie IODEF(BeginExternalListOutput)(
25 ExternalUnit unitNumber, const char *sourceFile, int sourceLine) {
26 return BeginExternalListIO<Direction::Output, ExternalListIoStatementState>(
27 unitNumber, sourceFile, sourceLine);
30 enum Iostat IODEF(EndIoStatement)(Cookie cookie) {
31 IoStatementState &io{*cookie};
32 return static_cast<enum Iostat>(io.EndIoStatement());
35 template <int KIND, typename INT = CppTypeFor<TypeCategory::Integer, KIND>>
36 inline RT_API_ATTRS bool FormattedScalarIntegerOutput(
37 IoStatementState &io, INT x, const char *whence) {
38 if (io.CheckFormattedStmtType<Direction::Output>(whence)) {
39 auto edit{io.GetNextDataEdit()};
40 return edit && EditIntegerOutput<KIND>(io, *edit, x);
41 } else {
42 return false;
46 bool IODEF(OutputInteger8)(Cookie cookie, std::int8_t n) {
47 return FormattedScalarIntegerOutput<1>(*cookie, n, "OutputInteger8");
50 bool IODEF(OutputInteger16)(Cookie cookie, std::int16_t n) {
51 return FormattedScalarIntegerOutput<2>(*cookie, n, "OutputInteger16");
54 bool IODEF(OutputInteger32)(Cookie cookie, std::int32_t n) {
55 return FormattedScalarIntegerOutput<4>(*cookie, n, "OutputInteger32");
58 bool IODEF(OutputInteger64)(Cookie cookie, std::int64_t n) {
59 return FormattedScalarIntegerOutput<8>(*cookie, n, "OutputInteger64");
62 #ifdef __SIZEOF_INT128__
63 bool IODEF(OutputInteger128)(Cookie cookie, common::int128_t n) {
64 return FormattedScalarIntegerOutput<16>(*cookie, n, "OutputInteger128");
66 #endif
68 template <int KIND,
69 typename REAL = typename RealOutputEditing<KIND>::BinaryFloatingPoint>
70 inline RT_API_ATTRS bool FormattedScalarRealOutput(
71 IoStatementState &io, REAL x, const char *whence) {
72 if (io.CheckFormattedStmtType<Direction::Output>(whence)) {
73 auto edit{io.GetNextDataEdit()};
74 return edit && RealOutputEditing<KIND>{io, x}.Edit(*edit);
75 } else {
76 return false;
80 bool IODEF(OutputReal32)(Cookie cookie, float x) {
81 return FormattedScalarRealOutput<4>(*cookie, x, "OutputReal32");
84 bool IODEF(OutputReal64)(Cookie cookie, double x) {
85 return FormattedScalarRealOutput<8>(*cookie, x, "OutputReal64");
88 template <int KIND,
89 typename REAL = typename RealOutputEditing<KIND>::BinaryFloatingPoint>
90 inline RT_API_ATTRS bool FormattedScalarComplexOutput(
91 IoStatementState &io, REAL re, REAL im, const char *whence) {
92 if (io.CheckFormattedStmtType<Direction::Output>(whence)) {
93 if (io.get_if<ListDirectedStatementState<Direction::Output>>() != nullptr) {
94 DataEdit rEdit, iEdit;
95 rEdit.descriptor = DataEdit::ListDirectedRealPart;
96 iEdit.descriptor = DataEdit::ListDirectedImaginaryPart;
97 rEdit.modes = iEdit.modes = io.mutableModes();
98 return RealOutputEditing<KIND>{io, re}.Edit(rEdit) &&
99 RealOutputEditing<KIND>{io, im}.Edit(iEdit);
100 } else {
101 auto reEdit{io.GetNextDataEdit()};
102 if (reEdit && RealOutputEditing<KIND>{io, re}.Edit(*reEdit)) {
103 auto imEdit{io.GetNextDataEdit()};
104 return imEdit && RealOutputEditing<KIND>{io, im}.Edit(*imEdit);
108 return false;
111 bool IODEF(OutputComplex32)(Cookie cookie, float re, float im) {
112 return FormattedScalarComplexOutput<4>(*cookie, re, im, "OutputComplex32");
115 bool IODEF(OutputComplex64)(Cookie cookie, double re, double im) {
116 return FormattedScalarComplexOutput<8>(*cookie, re, im, "OutputComplex64");
119 bool IODEF(OutputAscii)(Cookie cookie, const char *x, std::size_t length) {
120 IoStatementState &io{*cookie};
121 if (!x) {
122 io.GetIoErrorHandler().Crash("Null address for character output item");
123 } else if (auto *listOutput{
124 io.get_if<ListDirectedStatementState<Direction::Output>>()}) {
125 return ListDirectedCharacterOutput(io, *listOutput, x, length);
126 } else if (io.CheckFormattedStmtType<Direction::Output>("OutputAscii")) {
127 auto edit{io.GetNextDataEdit()};
128 return edit && EditCharacterOutput(io, *edit, x, length);
129 } else {
130 return false;
134 bool IODEF(OutputLogical)(Cookie cookie, bool truth) {
135 IoStatementState &io{*cookie};
136 if (auto *listOutput{
137 io.get_if<ListDirectedStatementState<Direction::Output>>()}) {
138 return ListDirectedLogicalOutput(io, *listOutput, truth);
139 } else if (io.CheckFormattedStmtType<Direction::Output>("OutputAscii")) {
140 auto edit{io.GetNextDataEdit()};
141 return edit && EditLogicalOutput(io, *edit, truth);
142 } else {
143 return false;
147 } // namespace Fortran::runtime::io
149 #if defined(_LIBCPP_VERBOSE_ABORT)
150 // Provide own definition for `std::__libcpp_verbose_abort` to avoid dependency
151 // on the version provided by libc++.
153 void std::__libcpp_verbose_abort(char const *format, ...) {
154 va_list list;
155 va_start(list, format);
156 std::vfprintf(stderr, format, list);
157 va_end(list);
159 std::abort();
161 #endif
163 RT_EXT_API_GROUP_END