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 14 bool StaticDataObject::bigEndian{false}; 15 AsFortran(llvm::raw_ostream & o) const16llvm::raw_ostream &StaticDataObject::AsFortran(llvm::raw_ostream &o) const { 17 if (auto string{AsString()}) { 18 o << parser::QuoteCharacterLiteral(*string); 19 } else if (auto string{AsU16String()}) { 20 o << "2_" << parser::QuoteCharacterLiteral(*string); 21 } else if (auto string{AsU32String()}) { 22 o << "4_" << parser::QuoteCharacterLiteral(*string); 23 } else { 24 CRASH_NO_CASE; 25 } 26 return o; 27 } 28 Push(const std::string & string)29StaticDataObject &StaticDataObject::Push(const std::string &string) { 30 for (auto ch : string) { 31 data_.push_back(static_cast<std::uint8_t>(ch)); 32 } 33 return *this; 34 } 35 Push(const std::u16string & string)36StaticDataObject &StaticDataObject::Push(const std::u16string &string) { 37 int shift{bigEndian * 8}; 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)45StaticDataObject &StaticDataObject::Push(const std::u32string &string) { 46 int shift{bigEndian * 24}; 47 for (auto ch : string) { 48 data_.push_back(static_cast<std::uint8_t>(ch >> shift)); 49 data_.push_back(static_cast<std::uint8_t>(ch >> (shift ^ 8))); 50 data_.push_back(static_cast<std::uint8_t>(ch >> (shift ^ 16))); 51 data_.push_back(static_cast<std::uint8_t>(ch >> (shift ^ 24))); 52 } 53 return *this; 54 } 55 AsString() const56std::optional<std::string> StaticDataObject::AsString() const { 57 if (itemBytes_ <= 1) { 58 std::string result; 59 for (std::uint8_t byte : data_) { 60 result += static_cast<char>(byte); 61 } 62 return {std::move(result)}; 63 } 64 return std::nullopt; 65 } 66 AsU16String() const67std::optional<std::u16string> StaticDataObject::AsU16String() const { 68 if (itemBytes_ == 2) { 69 int shift{bigEndian * 8}; 70 std::u16string result; 71 auto end{data_.cend()}; 72 for (auto byte{data_.cbegin()}; byte < end;) { 73 result += static_cast<char16_t>(*byte++) << shift | 74 static_cast<char16_t>(*byte++) << (shift ^ 8); 75 } 76 return {std::move(result)}; 77 } 78 return std::nullopt; 79 } 80 AsU32String() const81std::optional<std::u32string> StaticDataObject::AsU32String() const { 82 if (itemBytes_ == 4) { 83 int shift{bigEndian * 24}; 84 std::u32string result; 85 auto end{data_.cend()}; 86 for (auto byte{data_.cbegin()}; byte < end;) { 87 result += static_cast<char32_t>(*byte++) << shift | 88 static_cast<char32_t>(*byte++) << (shift ^ 8) | 89 static_cast<char32_t>(*byte++) << (shift ^ 16) | 90 static_cast<char32_t>(*byte++) << (shift ^ 24); 91 } 92 return {std::move(result)}; 93 } 94 return std::nullopt; 95 } 96 } // namespace Fortran::evaluate 97