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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "flang/Evaluate/static-data.h" 10 #include "flang/Parser/characters.h" 11 12 namespace Fortran::evaluate { 13 AsFortran(llvm::raw_ostream & o,bool bigEndian) const14llvm::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 Push(const std::string & string,bool)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 Push(const std::u16string & string,bool bigEndian)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 Push(const std::u32string & string,bool bigEndian)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 AsString() const57std::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 AsU16String(bool bigEndian) const68std::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 AsU32String(bool bigEndian) const83std::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::evaluate 100