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_ 14 #include "entry-names.h" 15 #include <cstddef> 16 17 namespace Fortran::runtime { 18 19 class Descriptor; 20 21 extern "C" { 22 23 // Appends the corresponding (or expanded) characters of 'operand' 24 // to the (elements of) a (re)allocation of 'accumulator', which must be an 25 // initialized CHARACTER allocatable scalar or array descriptor -- use 26 // AllocatableInitCharacter() to set one up. Crashes when not 27 // conforming. Assumes independence of data. 28 void RTNAME(CharacterConcatenate)(Descriptor &accumulator, 29 const Descriptor &from, const char *sourceFile = nullptr, 30 int sourceLine = 0); 31 32 // Convenience specialization for ASCII scalars concatenation. 33 void RTNAME(CharacterConcatenateScalar1)( 34 Descriptor &accumulator, const char *from, std::size_t chars); 35 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. 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 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)( 57 const char *x, const char *y, std::size_t xChars, std::size_t yChars); 58 int RTNAME(CharacterCompareScalar2)(const char16_t *x, const char16_t *y, 59 std::size_t xChars, std::size_t yChars); 60 int RTNAME(CharacterCompareScalar4)(const char32_t *x, const char32_t *y, 61 std::size_t xChars, std::size_t yChars); 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. 69 70 // Copies data from 'rhs' to the remaining space (lhsLength - offset) 71 // in 'lhs', if any. Returns the new offset. Assumes independence. 72 std::size_t RTNAME(CharacterAppend1)(char *lhs, std::size_t lhsBytes, 73 std::size_t offset, const char *rhs, std::size_t rhsBytes); 74 75 // Appends any necessary spaces to a CHARACTER(KIND=1) scalar. 76 void RTNAME(CharacterPad1)(char *lhs, std::size_t bytes, std::size_t offset); 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); 110 } 111 } // namespace Fortran::runtime 112 #endif // FORTRAN_RUNTIME_CHARACTER_H_ 113