peter klausler | 4d54bb7 | 2020-03-30 23:37:30 | [diff] [blame] | 1 | //===-- runtime/character.h -------------------------------------*- 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-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | // Defines API between compiled code and the CHARACTER |
| 10 | // support functions in the runtime library. |
| 11 | |
| 12 | #ifndef FORTRAN_RUNTIME_CHARACTER_H_ |
| 13 | #define FORTRAN_RUNTIME_CHARACTER_H_ |
peter klausler | 4d54bb7 | 2020-03-30 23:37:30 | [diff] [blame] | 14 | #include "entry-names.h" |
| 15 | #include <cstddef> |
| 16 | |
| 17 | namespace Fortran::runtime { |
peter klausler | fc02624 | 2020-04-24 00:07:45 | [diff] [blame] | 18 | |
| 19 | class Descriptor; |
| 20 | |
peter klausler | 4d54bb7 | 2020-03-30 23:37:30 | [diff] [blame] | 21 | extern "C" { |
| 22 | |
| 23 | // Appends the corresponding (or expanded) characters of 'operand' |
peter klausler | 3d627d6 | 2020-06-17 20:17:24 | [diff] [blame] | 24 | // to the (elements of) a (re)allocation of 'accumulator', which must be an |
peter klausler | 4d54bb7 | 2020-03-30 23:37:30 | [diff] [blame] | 25 | // initialized CHARACTER allocatable scalar or array descriptor -- use |
| 26 | // AllocatableInitCharacter() to set one up. Crashes when not |
| 27 | // conforming. Assumes independence of data. |
peter klausler | 3d627d6 | 2020-06-17 20:17:24 | [diff] [blame] | 28 | void RTNAME(CharacterConcatenate)(Descriptor &accumulator, |
| 29 | const Descriptor &from, const char *sourceFile = nullptr, |
| 30 | int sourceLine = 0); |
peter klausler | 4d54bb7 | 2020-03-30 23:37:30 | [diff] [blame] | 31 | |
peter klausler | 3d627d6 | 2020-06-17 20:17:24 | [diff] [blame] | 32 | // Convenience specialization for ASCII scalars concatenation. |
peter klausler | fc02624 | 2020-04-24 00:07:45 | [diff] [blame] | 33 | void RTNAME(CharacterConcatenateScalar1)( |
peter klausler | 3d627d6 | 2020-06-17 20:17:24 | [diff] [blame] | 34 | Descriptor &accumulator, const char *from, std::size_t chars); |
peter klausler | 4d54bb7 | 2020-03-30 23:37:30 | [diff] [blame] | 35 | |
peter klausler | 3d627d6 | 2020-06-17 20:17:24 | [diff] [blame] | 36 | // Copies the value(s) of 'rhs' to 'lhs'. Handles reallocation, |
| 37 | // truncation, or padding ss necessary. Crashes when not conforming and |
| 38 | // the LHS is not allocatable. Assumes independence of data. |
| 39 | // The LHS and RHS need not have the same kind of character; |
| 40 | // so when the LHS is a deallocated allocatable temporary result, this |
| 41 | // function can be used as a simple conversion routine. |
peter klausler | 4d54bb7 | 2020-03-30 23:37:30 | [diff] [blame] | 42 | // Call MoveAlloc() instead as an optimization when a temporary value is |
| 43 | // being assigned to a deferred-length allocatable. |
| 44 | void RTNAME(CharacterAssign)(Descriptor &lhs, const Descriptor &rhs, |
| 45 | const char *sourceFile = nullptr, int sourceLine = 0); |
| 46 | |
peter klausler | fc02624 | 2020-04-24 00:07:45 | [diff] [blame] | 47 | // CHARACTER comparisons. The kinds must match. Like std::memcmp(), |
| 48 | // the result is less than zero, zero, or greater than zero if the first |
| 49 | // argument is less than the second, equal to the second, or greater than |
| 50 | // the second, respectively. The shorter argument is treated as if it were |
| 51 | // padded on the right with blanks. |
| 52 | // N.B.: Calls to the restricted specific intrinsic functions LGE, LGT, LLE, |
| 53 | // & LLT are converted into calls to these during lowering; they don't have |
| 54 | // to be able to be passed as actual procedure arguments. |
| 55 | int RTNAME(CharacterCompareScalar)(const Descriptor &, const Descriptor &); |
| 56 | int RTNAME(CharacterCompareScalar1)( |
peter klausler | 3d627d6 | 2020-06-17 20:17:24 | [diff] [blame] | 57 | const char *x, const char *y, std::size_t xChars, std::size_t yChars); |
peter klausler | fc02624 | 2020-04-24 00:07:45 | [diff] [blame] | 58 | int RTNAME(CharacterCompareScalar2)(const char16_t *x, const char16_t *y, |
peter klausler | 3d627d6 | 2020-06-17 20:17:24 | [diff] [blame] | 59 | std::size_t xChars, std::size_t yChars); |
peter klausler | fc02624 | 2020-04-24 00:07:45 | [diff] [blame] | 60 | int RTNAME(CharacterCompareScalar4)(const char32_t *x, const char32_t *y, |
peter klausler | 3d627d6 | 2020-06-17 20:17:24 | [diff] [blame] | 61 | std::size_t xChars, std::size_t yChars); |
peter klausler | fc02624 | 2020-04-24 00:07:45 | [diff] [blame] | 62 | |
| 63 | // General CHARACTER comparison; the result is a LOGICAL(KIND=1) array that |
| 64 | // is established and populated. |
| 65 | void RTNAME(CharacterCompare)( |
| 66 | Descriptor &result, const Descriptor &, const Descriptor &); |
| 67 | |
| 68 | // Special-case support for optimized ASCII scalar expressions. |
peter klausler | 4d54bb7 | 2020-03-30 23:37:30 | [diff] [blame] | 69 | |
| 70 | // Copies data from 'rhs' to the remaining space (lhsLength - offset) |
| 71 | // in 'lhs', if any. Returns the new offset. Assumes independence. |
peter klausler | fc02624 | 2020-04-24 00:07:45 | [diff] [blame] | 72 | std::size_t RTNAME(CharacterAppend1)(char *lhs, std::size_t lhsBytes, |
| 73 | std::size_t offset, const char *rhs, std::size_t rhsBytes); |
peter klausler | 4d54bb7 | 2020-03-30 23:37:30 | [diff] [blame] | 74 | |
| 75 | // Appends any necessary spaces to a CHARACTER(KIND=1) scalar. |
peter klausler | fc02624 | 2020-04-24 00:07:45 | [diff] [blame] | 76 | void RTNAME(CharacterPad1)(char *lhs, std::size_t bytes, std::size_t offset); |
peter klausler | 3d627d6 | 2020-06-17 20:17:24 | [diff] [blame] | 77 | |
| 78 | // Intrinsic functions |
| 79 | // The result descriptors below are all established by the runtime. |
| 80 | void RTNAME(Adjustl)(Descriptor &result, const Descriptor &, |
| 81 | const char *sourceFile = nullptr, int sourceLine = 0); |
| 82 | void RTNAME(Adjustr)(Descriptor &result, const Descriptor &, |
| 83 | const char *sourceFile = nullptr, int sourceLine = 0); |
| 84 | std::size_t RTNAME(LenTrim1)(const char *, std::size_t); |
| 85 | std::size_t RTNAME(LenTrim2)(const char16_t *, std::size_t); |
| 86 | std::size_t RTNAME(LenTrim4)(const char32_t *, std::size_t); |
| 87 | void RTNAME(LenTrim)(Descriptor &result, const Descriptor &, int kind, |
| 88 | const char *sourceFile = nullptr, int sourceLine = 0); |
| 89 | void RTNAME(Repeat)(Descriptor &result, const Descriptor &string, |
| 90 | std::size_t ncopies, const char *sourceFile = nullptr, int sourceLine = 0); |
| 91 | void RTNAME(Trim)(Descriptor &result, const Descriptor &string, |
| 92 | const char *sourceFile = nullptr, int sourceLine = 0); |
| 93 | |
| 94 | void RTNAME(CharacterMax)(Descriptor &accumulator, const Descriptor &x, |
| 95 | const char *sourceFile = nullptr, int sourceLine = 0); |
| 96 | void RTNAME(CharacterMin)(Descriptor &accumulator, const Descriptor &x, |
| 97 | const char *sourceFile = nullptr, int sourceLine = 0); |
| 98 | void RTNAME(CharacterMaxVal)(Descriptor &result, const Descriptor &x, |
| 99 | int dim = 0, const Descriptor *mask = nullptr, |
| 100 | const char *sourceFile = nullptr, int sourceLine = 0); |
| 101 | void RTNAME(CharacterMinVal)(Descriptor &result, const Descriptor &x, |
| 102 | int dim = 0, const Descriptor *mask = nullptr, |
| 103 | const char *sourceFile = nullptr, int sourceLine = 0); |
| 104 | void RTNAME(CharacterMaxLoc)(Descriptor &result, const Descriptor &x, |
| 105 | int dim = 0, const Descriptor *mask = nullptr, int kind = sizeof(int), |
| 106 | bool back = false, const char *sourceFile = nullptr, int sourceLine = 0); |
| 107 | void RTNAME(CharacterMinLoc)(Descriptor &result, const Descriptor &x, |
| 108 | int dim = 0, const Descriptor *mask = nullptr, int kind = sizeof(int), |
| 109 | bool back = false, const char *sourceFile = nullptr, int sourceLine = 0); |
peter klausler | 4d54bb7 | 2020-03-30 23:37:30 | [diff] [blame] | 110 | } |
| 111 | } // namespace Fortran::runtime |
| 112 | #endif // FORTRAN_RUNTIME_CHARACTER_H_ |