100 lines · cpp
1//===-- lib/Evaluate/static-data.cpp --------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "flang/Evaluate/static-data.h"10#include "flang/Parser/characters.h"11 12namespace Fortran::evaluate {13 14llvm::raw_ostream &StaticDataObject::AsFortran(15 llvm::raw_ostream &o, bool bigEndian) const {16 if (auto string{AsString()}) {17 o << parser::QuoteCharacterLiteral(*string);18 } else if (auto string{AsU16String(bigEndian)}) {19 o << "2_" << parser::QuoteCharacterLiteral(*string);20 } else if (auto string{AsU32String(bigEndian)}) {21 o << "4_" << parser::QuoteCharacterLiteral(*string);22 } else {23 CRASH_NO_CASE;24 }25 return o;26}27 28StaticDataObject &StaticDataObject::Push(const std::string &string, bool) {29 for (auto ch : string) {30 data_.push_back(static_cast<std::uint8_t>(ch));31 }32 return *this;33}34 35StaticDataObject &StaticDataObject::Push(36 const std::u16string &string, bool bigEndian) {37 int shift{bigEndian ? 8 : 0};38 for (auto ch : string) {39 data_.push_back(static_cast<std::uint8_t>(ch >> shift));40 data_.push_back(static_cast<std::uint8_t>(ch >> (shift ^ 8)));41 }42 return *this;43}44 45StaticDataObject &StaticDataObject::Push(46 const std::u32string &string, bool bigEndian) {47 int shift{bigEndian ? 24 : 0};48 for (auto ch : string) {49 data_.push_back(static_cast<std::uint8_t>(ch >> shift));50 data_.push_back(static_cast<std::uint8_t>(ch >> (shift ^ 8)));51 data_.push_back(static_cast<std::uint8_t>(ch >> (shift ^ 16)));52 data_.push_back(static_cast<std::uint8_t>(ch >> (shift ^ 24)));53 }54 return *this;55}56 57std::optional<std::string> StaticDataObject::AsString() const {58 if (itemBytes_ <= 1) {59 std::string result;60 for (std::uint8_t byte : data_) {61 result += static_cast<char>(byte);62 }63 return {std::move(result)};64 }65 return std::nullopt;66}67 68std::optional<std::u16string> StaticDataObject::AsU16String(69 bool bigEndian) const {70 if (itemBytes_ == 2) {71 int shift{bigEndian ? 8 : 0};72 std::u16string result;73 auto end{data_.cend()};74 for (auto byte{data_.cbegin()}; byte < end;) {75 result += static_cast<char16_t>(*byte++) << shift |76 static_cast<char16_t>(*byte++) << (shift ^ 8);77 }78 return {std::move(result)};79 }80 return std::nullopt;81}82 83std::optional<std::u32string> StaticDataObject::AsU32String(84 bool bigEndian) const {85 if (itemBytes_ == 4) {86 int shift{bigEndian ? 24 : 0};87 std::u32string result;88 auto end{data_.cend()};89 for (auto byte{data_.cbegin()}; byte < end;) {90 result += static_cast<char32_t>(*byte++) << shift |91 static_cast<char32_t>(*byte++) << (shift ^ 8) |92 static_cast<char32_t>(*byte++) << (shift ^ 16) |93 static_cast<char32_t>(*byte++) << (shift ^ 24);94 }95 return {std::move(result)};96 }97 return std::nullopt;98}99} // namespace Fortran::evaluate100