[flang-commits] [flang] [llvm] [Flang] Introduce *Value classes with unittests (PR #216958)
Michael Kruse via flang-commits
flang-commits at lists.llvm.org
Thu Sep 17 03:51:44 PDT 2026
================
@@ -0,0 +1,257 @@
+//===-- include/flang/Evaluate/character-value-impl.h -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_EVALUATE_CHARACTER_VALUE_IMPL_H_
+#define FORTRAN_EVALUATE_CHARACTER_VALUE_IMPL_H_
+
+#include "flang/Evaluate/common.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cstddef>
+#include <optional>
+#include <string>
+#include <utility>
+#include <variant>
+
+namespace Fortran::evaluate::value {
+
+class CharacterValueImpl {
+ using Storage =
+ std::variant<std::monostate, std::string, std::u16string, std::u32string>;
+
+public:
+ // rule-of-five
+ ~CharacterValueImpl() = default;
+ CharacterValueImpl(const CharacterValueImpl &) = default;
+ CharacterValueImpl(CharacterValueImpl &&) = default;
+ CharacterValueImpl &operator=(const CharacterValueImpl &) = default;
+ CharacterValueImpl &operator=(CharacterValueImpl &&) = default;
+
+ CharacterValueImpl() = default;
+ explicit CharacterValueImpl(int kind, std::string s) {
+ withCharProto(kind, [&](auto c) {
+ using CharT = std::decay_t<decltype(c)>;
+ using StringT = std::basic_string<CharT>;
+ if (std::is_same_v<StringT, std::string>) {
+ storage_ = std::move(s);
+ } else {
+ StringT buf;
+ buf.resize(s.length());
+ for (auto [i, c] : llvm::enumerate(s)) {
+ buf[i] = c;
----------------
Meinersbur wrote:
The intent here was instead of providing overloads for char, char16_t, char32_t, to only use char32_t. All can be losslessly turnaround through char32_t and char32_t fits into a 32 register so shouldn't cause any performance loss.
The platform specific conversion was intended: use whatever the patform uses in the same way we do not force all platform to use little endian even on big endian machines (not even `Fortran::evaluate::Integer` is used this way, even if it had the capability to). In the end, the char32_t should be casted back to the original type before use.
`ICHAR` represents Fortran function which has its own semantic. It does not necessarily correspond to how characters are represented internally. #216960 changes it to explicitly mask out the widened bytes.
However, I can see that it cause confusion, so I am changing the implementation to always zero-extend.
https://github.com/llvm/llvm-project/pull/216958
More information about the flang-commits
mailing list