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