Warning: This file is not a C or C++ file. It does not have highlighting.

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
21namespace Fortran::evaluate {
22
23class InitialImage {
24public:
25 enum Result {
26 Ok,
27 NotAConstant,
28 OutOfRange,
29 SizeMismatch,
30 LengthMismatch,
31 TooManyElems
32 };
33
34 explicit InitialImage(std::size_t bytes) : data_(bytes) {}
35 InitialImage(InitialImage &&that) = default;
36
37 std::size_t size() const { return data_.size(); }
38
39 template <typename A>
40 Result Add(ConstantSubscript, std::size_t, const A &, FoldingContext &) {
41 return NotAConstant;
42 }
43 template <typename T>
44 Result Add(ConstantSubscript offset, std::size_t bytes, const Constant<T> &x,
45 FoldingContext &context) {
46 if (offset < 0 || offset + bytes > data_.size()) {
47 return OutOfRange;
48 } else {
49 auto elementBytes{ToInt64(x.GetType().MeasureSizeInBytes(context, true))};
50 if (!elementBytes ||
51 bytes !=
52 x.values().size() * static_cast<std::size_t>(*elementBytes)) {
53 return SizeMismatch;
54 } else if (bytes == 0) {
55 return Ok;
56 } else {
57 // TODO endianness
58 std::memcpy(&data_.at(offset), &x.values().at(0), bytes);
59 return Ok;
60 }
61 }
62 }
63 template <int KIND>
64 Result Add(ConstantSubscript offset, std::size_t bytes,
65 const Constant<Type<TypeCategory::Character, KIND>> &x,
66 FoldingContext &) {
67 if (offset < 0 || offset + bytes > data_.size()) {
68 return OutOfRange;
69 } else {
70 auto optElements{TotalElementCount(x.shape())};
71 if (!optElements) {
72 return TooManyElems;
73 }
74 auto elements{*optElements};
75 auto elementBytes{bytes > 0 ? bytes / elements : 0};
76 if (elements * elementBytes != bytes) {
77 return SizeMismatch;
78 } else if (bytes == 0) {
79 return Ok;
80 } else {
81 Result result{Ok};
82 for (auto at{x.lbounds()}; elements-- > 0; x.IncrementSubscripts(at)) {
83 auto scalar{x.At(at)}; // this is a std string; size() in chars
84 auto scalarBytes{scalar.size() * KIND};
85 if (scalarBytes != elementBytes) {
86 result = LengthMismatch;
87 }
88 // Blank padding when short
89 for (; scalarBytes < elementBytes; scalarBytes += KIND) {
90 scalar += ' ';
91 }
92 // TODO endianness
93 std::memcpy(&data_.at(offset), scalar.data(), elementBytes);
94 offset += elementBytes;
95 }
96 return result;
97 }
98 }
99 }
100 Result Add(ConstantSubscript, std::size_t, const Constant<SomeDerived> &,
101 FoldingContext &);
102 template <typename T>
103 Result Add(ConstantSubscript offset, std::size_t bytes, const Expr<T> &x,
104 FoldingContext &c) {
105 return common::visit(
106 [&](const auto &y) { return Add(offset, bytes, y, c); }, x.u);
107 }
108
109 void AddPointer(ConstantSubscript, const Expr<SomeType> &);
110
111 void Incorporate(ConstantSubscript toOffset, const InitialImage &from,
112 ConstantSubscript fromOffset, ConstantSubscript bytes);
113
114 // Conversions to constant initializers
115 std::optional<Expr<SomeType>> AsConstant(FoldingContext &,
116 const DynamicType &, std::optional<std::int64_t> charLength,
117 const ConstantSubscripts &, bool padWithZero = false,
118 ConstantSubscript offset = 0) const;
119 std::optional<Expr<SomeType>> AsConstantPointer(
120 ConstantSubscript offset = 0) const;
121
122 friend class AsConstantHelper;
123
124private:
125 std::vector<char> data_;
126 std::map<ConstantSubscript, Expr<SomeType>> pointers_;
127};
128
129} // namespace Fortran::evaluate
130#endif // FORTRAN_EVALUATE_INITIAL_IMAGE_H_
131

Warning: This file is not a C or C++ file. It does not have highlighting.

source code of flang/include/flang/Evaluate/initial-image.h