xref: /llvm-project/flang/include/flang/Runtime/assign.h (revision 42be165dde50c29e1d104f38938c03c95b4471cf)
1 //===-- include/flang/Runtime/assign.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 // External APIs for data assignment (both intrinsic assignment and TBP defined
10 // generic ASSIGNMENT(=)).  Should be called by lowering for any assignments
11 // possibly needing special handling.  Intrinsic assignment to non-allocatable
12 // variables whose types are intrinsic need not come through here (though they
13 // may do so).  Assignments to allocatables, and assignments whose types may be
14 // polymorphic or are monomorphic and of derived types with finalization,
15 // allocatable components, or components with type-bound defined assignments, in
16 // the original type or the types of its non-pointer components (recursively)
17 // must arrive here.
18 //
19 // Non-type-bound generic INTERFACE ASSIGNMENT(=) is resolved in semantics and
20 // need not be handled here in the runtime apart from derived type components;
21 // ditto for type conversions on intrinsic assignments.
22 
23 #ifndef FORTRAN_RUNTIME_ASSIGN_H_
24 #define FORTRAN_RUNTIME_ASSIGN_H_
25 
26 #include "flang/Runtime/entry-names.h"
27 #include "flang/Runtime/freestanding-tools.h"
28 
29 namespace Fortran::runtime {
30 class Descriptor;
31 class Terminator;
32 
33 enum AssignFlags {
34   NoAssignFlags = 0,
35   MaybeReallocate = 1 << 0,
36   NeedFinalization = 1 << 1,
37   CanBeDefinedAssignment = 1 << 2,
38   ComponentCanBeDefinedAssignment = 1 << 3,
39   ExplicitLengthCharacterLHS = 1 << 4,
40   PolymorphicLHS = 1 << 5,
41   DeallocateLHS = 1 << 6
42 };
43 
44 #ifdef RT_DEVICE_COMPILATION
45 RT_API_ATTRS void Assign(Descriptor &to, const Descriptor &from,
46     Terminator &terminator, int flags, MemmoveFct memmoveFct = &MemmoveWrapper);
47 #else
48 RT_API_ATTRS void Assign(Descriptor &to, const Descriptor &from,
49     Terminator &terminator, int flags,
50     MemmoveFct memmoveFct = &Fortran::runtime::memmove);
51 #endif
52 
53 extern "C" {
54 
55 // API for lowering assignment
56 void RTDECL(Assign)(Descriptor &to, const Descriptor &from,
57     const char *sourceFile = nullptr, int sourceLine = 0);
58 // This variant has no finalization, defined assignment, or allocatable
59 // reallocation.
60 void RTDECL(AssignTemporary)(Descriptor &to, const Descriptor &from,
61     const char *sourceFile = nullptr, int sourceLine = 0);
62 
63 // Establish "temp" descriptor as an allocatable descriptor with the same type,
64 // rank, and length parameters as "var" and copy "var" to it using
65 // AssignTemporary.
66 void RTDECL(CopyInAssign)(Descriptor &temp, const Descriptor &var,
67     const char *sourceFile = nullptr, int sourceLine = 0);
68 // When "var" is provided, copy "temp" to it assuming "var" is already
69 // initialized. Destroy and deallocate "temp" in all cases.
70 void RTDECL(CopyOutAssign)(Descriptor *var, Descriptor &temp,
71     const char *sourceFile = nullptr, int sourceLine = 0);
72 // This variant is for assignments to explicit-length CHARACTER left-hand
73 // sides that might need to handle truncation or blank-fill, and
74 // must maintain the character length even if an allocatable array
75 // is reallocated.
76 void RTDECL(AssignExplicitLengthCharacter)(Descriptor &to,
77     const Descriptor &from, const char *sourceFile = nullptr,
78     int sourceLine = 0);
79 // This variant is assignments to whole polymorphic allocatables.
80 void RTDECL(AssignPolymorphic)(Descriptor &to, const Descriptor &from,
81     const char *sourceFile = nullptr, int sourceLine = 0);
82 } // extern "C"
83 } // namespace Fortran::runtime
84 #endif // FORTRAN_RUNTIME_ASSIGN_H_
85