brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · fdf7183 Raw
165 lines · cpp
1//===-- lib/runtime/io-api-minimal.cpp --------------------------*- C++ -*-===//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-exception6//7//===----------------------------------------------------------------------===//8 9// Implements the subset of the I/O statement API needed for basic10// list-directed output (PRINT *) of intrinsic types.11 12#include "edit-output.h"13#include "io-api-common.h"14#include "unit.h"15#include "flang-rt/runtime/format.h"16#include "flang-rt/runtime/io-stmt.h"17#include "flang-rt/runtime/terminator.h"18#include "flang-rt/runtime/tools.h"19#include "flang/Runtime/io-api.h"20 21namespace Fortran::runtime::io {22RT_EXT_API_GROUP_BEGIN23 24Cookie IODEF(BeginExternalListOutput)(25    ExternalUnit unitNumber, const char *sourceFile, int sourceLine) {26  return BeginExternalListIO<Direction::Output, ExternalListIoStatementState>(27      unitNumber, sourceFile, sourceLine);28}29 30enum Iostat IODEF(EndIoStatement)(Cookie cookie) {31  IoStatementState &io{*cookie};32  return static_cast<enum Iostat>(io.EndIoStatement());33}34 35template <int KIND, typename INT = CppTypeFor<TypeCategory::Integer, KIND>>36inline 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, /*isSigned=*/true);41  } else {42    return false;43  }44}45 46bool IODEF(OutputInteger8)(Cookie cookie, std::int8_t n) {47  return FormattedScalarIntegerOutput<1>(*cookie, n, "OutputInteger8");48}49 50bool IODEF(OutputInteger16)(Cookie cookie, std::int16_t n) {51  return FormattedScalarIntegerOutput<2>(*cookie, n, "OutputInteger16");52}53 54bool IODEF(OutputInteger32)(Cookie cookie, std::int32_t n) {55  return FormattedScalarIntegerOutput<4>(*cookie, n, "OutputInteger32");56}57 58bool IODEF(OutputInteger64)(Cookie cookie, std::int64_t n) {59  return FormattedScalarIntegerOutput<8>(*cookie, n, "OutputInteger64");60}61 62#ifdef __SIZEOF_INT128__63bool IODEF(OutputInteger128)(Cookie cookie, common::int128_t n) {64  return FormattedScalarIntegerOutput<16>(*cookie, n, "OutputInteger128");65}66#endif67 68template <int KIND,69    typename REAL = typename RealOutputEditing<KIND>::BinaryFloatingPoint>70inline 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;77  }78}79 80bool IODEF(OutputReal32)(Cookie cookie, float x) {81  return FormattedScalarRealOutput<4>(*cookie, x, "OutputReal32");82}83 84bool IODEF(OutputReal64)(Cookie cookie, double x) {85  return FormattedScalarRealOutput<8>(*cookie, x, "OutputReal64");86}87 88template <int KIND,89    typename REAL = typename RealOutputEditing<KIND>::BinaryFloatingPoint>90inline 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);105      }106    }107  }108  return false;109}110 111bool IODEF(OutputComplex32)(Cookie cookie, float re, float im) {112  return FormattedScalarComplexOutput<4>(*cookie, re, im, "OutputComplex32");113}114 115bool IODEF(OutputComplex64)(Cookie cookie, double re, double im) {116  return FormattedScalarComplexOutput<8>(*cookie, re, im, "OutputComplex64");117}118 119bool 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;131  }132}133 134bool 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;144  }145}146 147} // namespace Fortran::runtime::io148 149#if defined(_LIBCPP_VERBOSE_ABORT)150// Provide own definition for `std::__libcpp_verbose_abort` to avoid dependency151// on the version provided by libc++.152 153void std::__libcpp_verbose_abort(char const *format, ...) noexcept(154    noexcept(std::__libcpp_verbose_abort(""))) {155  va_list list;156  va_start(list, format);157  std::vfprintf(stderr, format, list);158  va_end(list);159 160  std::abort();161}162#endif163 164RT_EXT_API_GROUP_END165