FLANG

initial-image.h
1 //===-------include/flang/Evaluate/initial-image.h ------------------------===//
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 #ifndef FORTRAN_EVALUATE_INITIAL_IMAGE_H_
10 #define FORTRAN_EVALUATE_INITIAL_IMAGE_H_
11
12 // Represents the initialized storage of an object during DATA statement
13 // processing, including the conversion of that image to a constant
14 // initializer for a symbol.
15
16 #include "expression.h"
17 #include <map>
18 #include <optional>
19 #include <vector>
20
21 namespace Fortran::evaluate {
22
23 class InitialImage {
24 public:
25 enum Result {
26 Ok,
27 NotAConstant,
28 OutOfRange,
29 SizeMismatch,
30 };
31
32 explicit InitialImage(std::size_t bytes) : data_(bytes) {}
33
34 std::size_t size() const { return data_.size(); }
35
36 template <typename A> Result Add(ConstantSubscript, std::size_t, const A &) {
37 return NotAConstant;
38 }
39 template <typename T>
40 Result Add(
41 ConstantSubscript offset, std::size_t bytes, const Constant<T> &x) {
42 if (offset < 0 || offset + bytes > data_.size()) {
43 return OutOfRange;
44 } else {
45 auto elementBytes{x.GetType().MeasureSizeInBytes()};
46 if (!elementBytes || bytes != x.values().size() * *elementBytes) {
47 return SizeMismatch;
48 } else {
49 std::memcpy(&data_.at(offset), &x.values().at(0), bytes);
50 return Ok;
51 }
52 }
53 }
54 template <int KIND>
55 Result Add(ConstantSubscript offset, std::size_t bytes,
56 const Constant<Type<TypeCategory::Character, KIND>> &x) {
57 if (offset < 0 || offset + bytes > data_.size()) {
58 return OutOfRange;
59 } else {
60 auto elements{TotalElementCount(x.shape())};
61 auto elementBytes{bytes > 0 ? bytes / elements : 0};
62 if (elements * elementBytes != bytes) {
63 return SizeMismatch;
64 } else {
65 for (auto at{x.lbounds()}; elements-- > 0; x.IncrementSubscripts(at)) {
66 auto scalar{x.At(at)}; // this is a std string; size() in chars
67 // Subtle: an initializer for a substring may have been
68 // expanded to the length of the entire string.
69 auto scalarBytes{scalar.size() * KIND};
70 if (scalarBytes < elementBytes ||
71 (scalarBytes > elementBytes && elements != 0)) {
72 return SizeMismatch;
73 }
74 std::memcpy(&data_[offset], scalar.data(), elementBytes);
75 offset += elementBytes;
76 }
77 return Ok;
78 }
79 }
80 }
81 Result Add(ConstantSubscript, std::size_t, const Constant<SomeDerived> &);
82 template <typename T>
83 Result Add(ConstantSubscript offset, std::size_t bytes, const Expr<T> &x) {
84 return std::visit(
85 [&](const auto &y) { return Add(offset, bytes, y); }, x.u);
86 }
87
88 void AddPointer(ConstantSubscript, const Expr<SomeType> &);
89
90 // Conversions to constant initializers
91 std::optional<Expr<SomeType>> AsConstant(FoldingContext &,
92 const DynamicType &, const ConstantSubscripts &,
93 ConstantSubscript offset = 0) const;
94 std::optional<Expr<SomeType>> AsConstantDataPointer(
95 const DynamicType &, ConstantSubscript offset = 0) const;
96 const ProcedureDesignator &AsConstantProcPointer(
97 ConstantSubscript offset = 0) const;
98
99 friend class AsConstantHelper;
100 friend class AsConstantDataPointerHelper;
101
102 private:
103 std::vector<char> data_;
104 std::map<ConstantSubscript, Expr<SomeType>> pointers_;
105 };
106
107 } // namespace Fortran::evaluate
108 #endif // FORTRAN_EVALUATE_INITIAL_IMAGE_H_
Fortran::evaluate::Expr< SomeType >
Definition: expression.h:784
Fortran::evaluate::Constant
Definition: constant.h:40
Fortran::evaluate::Add
Definition: expression.h:278
Fortran::evaluate::Constant< SomeDerived >
Definition: constant.h:202
Fortran::evaluate::DynamicType
Definition: type.h:85
Fortran::evaluate::AsConstantHelper
Definition: initial-image.cpp:59
Fortran::evaluate::Type
Definition: type.h:48
Fortran::evaluate::FoldingContext
Definition: common.h:209
Fortran::evaluate::InitialImage
Definition: initial-image.h:23
Fortran::evaluate::ProcedureDesignator
Definition: call.h:159
Fortran::evaluate::AsConstantDataPointerHelper
Definition: initial-image.cpp:152
Fortran::evaluate::Expr
Definition: common.h:207