diff --git a/gcc/rust/lex/rust-token.h b/gcc/rust/lex/rust-token.h index c7ec753a123..716b3ce3686 100644 --- a/gcc/rust/lex/rust-token.h +++ b/gcc/rust/lex/rust-token.h @@ -456,4 +456,16 @@ return *str; }; } // namespace Rust +namespace std { +template <> struct hash +{ + size_t operator() (const Rust::PrimitiveCoreType &coretype) const noexcept + { + return hash::type> () ( + static_cast::type> ( + coretype)); + } +}; +} // namespace std + #endif diff --git a/gcc/rust/util/rust-token-converter.cc b/gcc/rust/util/rust-token-converter.cc index 2047ea72967..d56493f5411 100644 --- a/gcc/rust/util/rust-token-converter.cc +++ b/gcc/rust/util/rust-token-converter.cc @@ -17,9 +17,28 @@ #include "rust-lex.h" #include "rust-token-converter.h" #include "libproc_macro/proc_macro.h" +#include "bi-map.h" + +#include namespace Rust { +static const BiMap suffixes + = {{{CORETYPE_F32, "f32"}, + {CORETYPE_F64, "f64"}, + {CORETYPE_U8, "u8"}, + {CORETYPE_U16, "u16"}, + {CORETYPE_U32, "u32"}, + {CORETYPE_U64, "u64"}, + {CORETYPE_U128, "u128"}, + {CORETYPE_I8, "i8"}, + {CORETYPE_I16, "i16"}, + {CORETYPE_I32, "i32"}, + {CORETYPE_I64, "i64"}, + {CORETYPE_I128, "i128"}, + {CORETYPE_ISIZE, "isize"}, + {CORETYPE_USIZE, "usize"}}}; + static void pop_group (std::vector &streams, ProcMacro::Delimiter delim) @@ -35,93 +54,24 @@ static void dispatch_float_literals (ProcMacro::TokenStream &ts, const const_TokenPtr &token) { - std::string::size_type sz; auto str = token->as_string (); - switch (token->get_type_hint ()) - { - case CORETYPE_F32: { - auto value = std::stof (str, &sz); - ts.push (ProcMacro::TokenTree::make_tokentree ( - ProcMacro::Literal::make_f32 (value, sz != str.length ()))); - } - break; - case CORETYPE_F64: { - auto value = std::stod (str, &sz); - ts.push (ProcMacro::TokenTree::make_tokentree ( - ProcMacro::Literal::make_f64 (value, sz != str.length ()))); - } - break; - default: - gcc_unreachable (); - } + auto kind = ProcMacro::LitKind::make_float (); + auto lookup = suffixes.lookup (token->get_type_hint ()); + auto suffix = suffixes.is_iter_ok (lookup) ? lookup->second : ""; + ts.push (ProcMacro::TokenTree::make_tokentree ( + ProcMacro::Literal::make_literal (kind, str, suffix))); } static void dispatch_integer_literals (ProcMacro::TokenStream &ts, const const_TokenPtr &token) { - std::string::size_type sz; auto str = token->as_string (); - unsigned long long uvalue; - long long svalue; - - switch (token->get_type_hint ()) - { - case CORETYPE_U8: - uvalue = std::stoull (str, &sz); - ts.push (ProcMacro::TokenTree::make_tokentree ( - ProcMacro::Literal::make_u8 (uvalue, sz != str.length ()))); - break; - case CORETYPE_U16: - uvalue = std::stoull (str, &sz); - ts.push (ProcMacro::TokenTree::make_tokentree ( - ProcMacro::Literal::make_u16 (uvalue, sz != str.length ()))); - break; - case CORETYPE_U32: - uvalue = std::stoull (str, &sz); - ts.push (ProcMacro::TokenTree::make_tokentree ( - ProcMacro::Literal::make_u32 (uvalue, sz != str.length ()))); - break; - case CORETYPE_U64: - uvalue = std::stoull (str, &sz); - ts.push (ProcMacro::TokenTree::make_tokentree ( - ProcMacro::Literal::make_u32 (uvalue, sz != str.length ()))); - break; - case CORETYPE_I8: - svalue = std::stoll (str, &sz); - ts.push (ProcMacro::TokenTree::make_tokentree ( - ProcMacro::Literal::make_i8 (svalue, sz != str.length ()))); - break; - case CORETYPE_I16: - svalue = std::stoll (str, &sz); - ts.push (ProcMacro::TokenTree::make_tokentree ( - ProcMacro::Literal::make_i16 (svalue, sz != str.length ()))); - break; - case CORETYPE_I32: - svalue = std::stoll (str, &sz); - ts.push (ProcMacro::TokenTree::make_tokentree ( - ProcMacro::Literal::make_i32 (svalue, sz != str.length ()))); - break; - case CORETYPE_I64: - svalue = std::stoll (str, &sz); - ts.push (ProcMacro::TokenTree::make_tokentree ( - ProcMacro::Literal::make_i32 (svalue, sz != str.length ()))); - break; - case CORETYPE_INT: - svalue = std::stoll (str, &sz); - ts.push (ProcMacro::TokenTree::make_tokentree ( - ProcMacro::Literal::make_isize (svalue, sz != str.length ()))); - break; - case CORETYPE_UINT: - uvalue = std::stoull (str, &sz); - ts.push (ProcMacro::TokenTree::make_tokentree ( - ProcMacro::Literal::make_usize (uvalue, sz != str.length ()))); - break; - case CORETYPE_UNKNOWN: - default: - gcc_unreachable (); - break; - } + auto kind = ProcMacro::LitKind::make_integer (); + auto lookup = suffixes.lookup (token->get_type_hint ()); + auto suffix = suffixes.is_iter_ok (lookup) ? lookup->second : ""; + ts.push (ProcMacro::TokenTree::make_tokentree ( + ProcMacro::Literal::make_literal (kind, str, suffix))); } ProcMacro::TokenStream @@ -140,21 +90,25 @@ convert (const std::vector &tokens) case INT_LITERAL: dispatch_integer_literals (trees.back (), token); break; - // FIXME: Why does BYTE_CHAR_LITERAL is not handled by rustc ? - case CHAR_LITERAL: // TODO: UTF-8 handling + case CHAR_LITERAL: trees.back ().push (ProcMacro::TokenTree::make_tokentree ( - ProcMacro::Literal::make_char (token->as_string ()[0]))); + ProcMacro::Literal::make_literal (ProcMacro::LitKind::make_char (), + token->as_string ()))); break; case STRING_LITERAL: trees.back ().push (ProcMacro::TokenTree::make_tokentree ( - ProcMacro::Literal::make_string (token->as_string ()))); + ProcMacro::Literal::make_literal (ProcMacro::LitKind::make_str (), + token->as_string ()))); break; - case BYTE_STRING_LITERAL: { - auto str = token->as_string (); - std::vector data (str.begin (), str.end ()); - trees.back ().push (ProcMacro::TokenTree::make_tokentree ( - ProcMacro::Literal::make_byte_string (data))); - } + case BYTE_CHAR_LITERAL: + trees.back ().push (ProcMacro::TokenTree::make_tokentree ( + ProcMacro::Literal::make_literal (ProcMacro::LitKind::make_byte (), + token->as_string ()))); + break; + case BYTE_STRING_LITERAL: + trees.back ().push (ProcMacro::TokenTree::make_tokentree ( + ProcMacro::Literal::make_literal ( + ProcMacro::LitKind::make_byte_str (), token->as_string ()))); break; // Ident case IDENTIFIER: @@ -321,91 +275,6 @@ from_ident (const ProcMacro::Ident &ident, std::vector &result) result.push_back (lexer.peek_token ()); } -static void -string_literal (const ProcMacro::StringPayload &payload, - std::vector &result) -{ - // TODO: UTF-8 string - result.push_back (Token::make_string ( - Location (), - std::string (reinterpret_cast (payload.data), payload.len))); -} - -static void -byte_string_literal (const ProcMacro::ByteStringPayload &payload, - std::vector &result) -{ - result.push_back (Token::make_byte_string ( - Location (), - std::string (reinterpret_cast (payload.data), payload.size))); -} - -static void -unsigned_literal (const ProcMacro::Unsigned &lit, - std::vector &result) -{ - switch (lit.tag) - { - case ProcMacro::UNSIGNED_8: - result.push_back (Token::make_int (Location (), - std::to_string (lit.payload.unsigned8), - CORETYPE_U8)); - break; - case ProcMacro::UNSIGNED_16: - result.push_back ( - Token::make_int (Location (), std::to_string (lit.payload.unsigned16), - CORETYPE_U16)); - break; - case ProcMacro::UNSIGNED_32: - result.push_back ( - Token::make_int (Location (), std::to_string (lit.payload.unsigned32), - CORETYPE_U32)); - break; - case ProcMacro::UNSIGNED_64: - result.push_back ( - Token::make_int (Location (), std::to_string (lit.payload.unsigned64), - CORETYPE_U64)); - break; - case ProcMacro::UNSIGNED_128: - // TODO: Handle 128 bits - default: - gcc_unreachable (); - } -} - -static void -signed_literal (const ProcMacro::Signed &lit, - std::vector &result) -{ - switch (lit.tag) - { - case ProcMacro::SIGNED_8: - result.push_back (Token::make_int (Location (), - std::to_string (lit.payload.signed8), - CORETYPE_I8)); - break; - case ProcMacro::SIGNED_16: - result.push_back (Token::make_int (Location (), - std::to_string (lit.payload.signed16), - CORETYPE_I16)); - break; - case ProcMacro::SIGNED_32: - result.push_back (Token::make_int (Location (), - std::to_string (lit.payload.signed32), - CORETYPE_I32)); - break; - case ProcMacro::SIGNED_64: - result.push_back (Token::make_int (Location (), - std::to_string (lit.payload.signed64), - CORETYPE_I64)); - break; - case ProcMacro::SIGNED_128: - // TODO: Handle 128 bits - default: - gcc_unreachable (); - } -} - /** * Append the token corresponding to a given Literal to a vector. * @@ -416,46 +285,39 @@ static void from_literal (const ProcMacro::Literal &literal, std::vector &result) { - switch (literal.tag) + auto lookup = suffixes.lookup (literal.suffix.to_string ()); + auto suffix + = suffixes.is_iter_ok (lookup) ? lookup->second : CORETYPE_UNKNOWN; + // FIXME: Add spans instead of empty locations + switch (literal.kind.tag) { - case ProcMacro::STRING: - string_literal (literal.payload.string_payload, result); - break; - case ProcMacro::BYTE_STRING: - byte_string_literal (literal.payload.byte_string_payload, result); + case ProcMacro::BYTE: + result.push_back ( + Token::make_byte_char (Location (), literal.text.to_string ()[0])); break; case ProcMacro::CHAR: result.push_back ( - Token::make_char (Location (), literal.payload.char_payload)); + Token::make_char (Location (), literal.text.to_string ()[0])); break; - case ProcMacro::UNSIGNED: - unsigned_literal (literal.payload.unsigned_payload.value, result); - break; - case ProcMacro::SIGNED: - signed_literal (literal.payload.signed_payload.value, result); - break; - case ProcMacro::USIZE: + case ProcMacro::INTEGER: result.push_back ( - Token::make_int (Location (), - std::to_string (literal.payload.usize_payload.value), - CORETYPE_USIZE)); + Token::make_int (Location (), literal.text.to_string (), suffix)); break; - case ProcMacro::ISIZE: + case ProcMacro::FLOAT: result.push_back ( - Token::make_int (Location (), - std::to_string (literal.payload.isize_payload.value), - CORETYPE_ISIZE)); + Token::make_float (Location (), literal.text.to_string (), suffix)); break; - case ProcMacro::FLOAT32: - result.push_back (Token::make_float ( - Location (), std::to_string (literal.payload.float32_payload.value), - CORETYPE_F32)); + case ProcMacro::STR: + result.push_back ( + Token::make_string (Location (), literal.text.to_string ())); break; - case ProcMacro::FLOAT64: - result.push_back (Token::make_float ( - Location (), std::to_string (literal.payload.float64_payload.value), - CORETYPE_F64)); + case ProcMacro::BYTE_STR: + result.push_back ( + Token::make_byte_string (Location (), literal.text.to_string ())); break; + // FIXME: Handle raw string + case ProcMacro::STR_RAW: + case ProcMacro::BYTE_STR_RAW: default: gcc_unreachable (); } diff --git a/libgrust/libproc_macro/Makefile.am b/libgrust/libproc_macro/Makefile.am index 0fe22114248..493508cd9ee 100644 --- a/libgrust/libproc_macro/Makefile.am +++ b/libgrust/libproc_macro/Makefile.am @@ -52,7 +52,14 @@ LIBOBJS = @LIBOBJS@ objext = @OBJEXT@ REQUIRED_OFILES = \ - ./proc_macro.$(objext) ./literal.$(objext) ./group.$(objext) ./ident.$(objext) ./punct.$(objext) ./tokenstream.$(objext) ./tokentree.$(objext) + ./proc_macro.$(objext) \ + ./literal.$(objext) \ + ./group.$(objext) \ + ./ident.$(objext) \ + ./punct.$(objext) \ + ./tokenstream.$(objext) \ + ./tokentree.$(objext) \ + ./ffistring.$(objext) all: $(TARGETLIB) diff --git a/libgrust/libproc_macro/Makefile.in b/libgrust/libproc_macro/Makefile.in index 6eb5365d1ac..36031effcab 100644 --- a/libgrust/libproc_macro/Makefile.in +++ b/libgrust/libproc_macro/Makefile.in @@ -311,7 +311,14 @@ AM_MAKEFLAGS = \ TARGETLIB = ./libproc_macro.a objext = @OBJEXT@ REQUIRED_OFILES = \ - ./proc_macro.$(objext) ./literal.$(objext) ./group.$(objext) ./ident.$(objext) ./punct.$(objext) ./tokenstream.$(objext) ./tokentree.$(objext) + ./proc_macro.$(objext) \ + ./literal.$(objext) \ + ./group.$(objext) \ + ./ident.$(objext) \ + ./punct.$(objext) \ + ./tokenstream.$(objext) \ + ./tokentree.$(objext) \ + ./ffistring.$(objext) all: all-am diff --git a/libgrust/libproc_macro/ffistring.cc b/libgrust/libproc_macro/ffistring.cc new file mode 100644 index 00000000000..1623bc9899e --- /dev/null +++ b/libgrust/libproc_macro/ffistring.cc @@ -0,0 +1,62 @@ +// Copyright (C) 2023 Free Software Foundation, Inc. +// +// This file is part of the GNU Proc Macro Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +#include +#include "ffistring.h" + +namespace ProcMacro { +void +FFIString::drop (FFIString *str) +{ + delete[] str->data; + str->len = 0; +} + +FFIString +FFIString::make_ffistring (const std::string &str) +{ + return make_ffistring (reinterpret_cast (str.c_str ()), + str.length ()); +} + +FFIString +FFIString::make_ffistring (const unsigned char *data, std::uint64_t len) +{ + const unsigned char *inner = new unsigned char[len]; + return {inner, len}; +} + +FFIString +FFIString::clone () const +{ + unsigned char *inner = new unsigned char[this->len]; + std::memcpy (inner, this->data, this->len); + return {inner, this->len}; +} + +std::string +FFIString::to_string () const +{ + return std::string (reinterpret_cast (this->data), this->len); +} + +} // namespace ProcMacro diff --git a/libgrust/libproc_macro/ffistring.h b/libgrust/libproc_macro/ffistring.h new file mode 100644 index 00000000000..c151645ee5f --- /dev/null +++ b/libgrust/libproc_macro/ffistring.h @@ -0,0 +1,55 @@ +// Copyright (C) 2023 Free Software Foundation, Inc. +// +// This file is part of the GNU Proc Macro Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +#ifndef FFISTRING_H +#define FFISTRING_H + +#include +#include + +namespace ProcMacro { + +struct FFIString +{ + const unsigned char *data; + std::uint64_t len; + +public: + FFIString clone () const; + std::string to_string () const; + static FFIString make_ffistring (const std::string &str); + static FFIString make_ffistring (const unsigned char *data, + std::uint64_t len); + static void drop (FFIString *str); +}; + +extern "C" { +FFIString +FFIString__new (const unsigned char *data, std::uint64_t len); + +void +FFIString__drop (FFIString *str); +} + +} // namespace ProcMacro + +#endif /* ! FFISTRING_H */ diff --git a/libgrust/libproc_macro/literal.cc b/libgrust/libproc_macro/literal.cc index 39474ce3120..e3d171f7268 100644 --- a/libgrust/libproc_macro/literal.cc +++ b/libgrust/libproc_macro/literal.cc @@ -26,266 +26,216 @@ namespace ProcMacro { -void -Literal::drop (Literal *lit) -{ - switch (lit->tag) - { - case STRING: - delete[] lit->payload.string_payload.data; - lit->payload.string_payload.len = 0; - break; - case BYTE_STRING: - delete[] lit->payload.byte_string_payload.data; - lit->payload.byte_string_payload.size = 0; - break; - case CHAR: - case UNSIGNED: - case SIGNED: - case USIZE: - case ISIZE: - case FLOAT32: - case FLOAT64: - break; - } -} - extern "C" { - -void -Literal__drop (Literal *lit) -{ - Literal::drop (lit); -} - -Literal -Literal__string (const unsigned char *str, std::uint64_t len) -{ - return Literal::make_string (str, len); -} - -Literal -Literal__byte_string (const std::uint8_t *bytes, std::uint64_t len) -{ - return Literal::make_byte_string (bytes, len); -} - bool Literal__from_string (const unsigned char *str, std::uint64_t len, Literal *lit) { - // FIXME: implement this function with parser + // FIXME: implement this function with lexer std::abort (); return false; } } -Literal -Literal::make_unsigned (UnsignedSuffixPayload p) +void +Literal::drop (Literal *lit) { - LiteralPayload payload; - payload.unsigned_payload = p; - return {UNSIGNED, payload}; -} - -Literal -Literal::make_signed (SignedSuffixPayload p) -{ - LiteralPayload payload; - payload.signed_payload = p; - return {SIGNED, payload}; + FFIString::drop (&lit->text); + FFIString::drop (&lit->suffix); } Literal Literal::clone () const { - Literal lit = *this; - switch (this->tag) - { - case STRING: - lit.payload.string_payload.data - = new unsigned char[lit.payload.string_payload.len]; - std::memcpy (lit.payload.string_payload.data, - this->payload.string_payload.data, - lit.payload.string_payload.len); - break; - case BYTE_STRING: - lit.payload.byte_string_payload.data - = new uint8_t[lit.payload.byte_string_payload.size]; - std::memcpy (lit.payload.byte_string_payload.data, - this->payload.byte_string_payload.data, - lit.payload.byte_string_payload.size); - break; - default: - break; - } - return lit; + return {this->kind, this->text.clone (), this->has_suffix, + this->suffix.clone ()}; +} + +Literal +Literal::make_literal (LitKind kind, const std::string &text, + const std::string &suffix) +{ + auto ffi_text = FFIString::make_ffistring (text); + auto ffi_suffix = FFIString::make_ffistring (suffix); + return {kind, ffi_text, suffix != "", ffi_suffix}; } Literal Literal::make_u8 (std::uint8_t value, bool suffixed) { - UnsignedPayload unsigned_payload; - unsigned_payload.unsigned8 = value; - Unsigned val{UNSIGNED_8, unsigned_payload}; - UnsignedSuffixPayload payload{val, suffixed}; - - return make_unsigned (payload); + auto text = FFIString::make_ffistring (std::to_string (value)); + auto suffix = FFIString::make_ffistring (suffixed ? "u8" : ""); + return {LitKind::make_integer (), text, suffixed, suffix}; } Literal Literal::make_u16 (std::uint16_t value, bool suffixed) { - UnsignedPayload unsigned_payload; - unsigned_payload.unsigned16 = value; - Unsigned val{UNSIGNED_16, unsigned_payload}; - UnsignedSuffixPayload payload{val, suffixed}; - - return make_unsigned (payload); + auto text = FFIString::make_ffistring (std::to_string (value)); + auto suffix = FFIString::make_ffistring (suffixed ? "u16" : ""); + return {LitKind::make_integer (), text, suffixed, suffix}; } Literal Literal::make_u32 (std::uint32_t value, bool suffixed) { - UnsignedPayload unsigned_payload; - unsigned_payload.unsigned32 = value; - Unsigned val{UNSIGNED_32, unsigned_payload}; - UnsignedSuffixPayload payload{val, suffixed}; - - return make_unsigned (payload); + auto text = FFIString::make_ffistring (std::to_string (value)); + auto suffix = FFIString::make_ffistring (suffixed ? "u32" : ""); + return {LitKind::make_integer (), text, suffixed, suffix}; } Literal Literal::make_u64 (std::uint64_t value, bool suffixed) { - UnsignedPayload unsigned_payload; - unsigned_payload.unsigned64 = value; - Unsigned val{UNSIGNED_64, unsigned_payload}; - UnsignedSuffixPayload payload{val, suffixed}; - - return make_unsigned (payload); + auto text = FFIString::make_ffistring (std::to_string (value)); + auto suffix = FFIString::make_ffistring (suffixed ? "u64" : ""); + return {LitKind::make_integer (), text, suffixed, suffix}; } Literal Literal::make_i8 (std::int8_t value, bool suffixed) { - SignedPayload signed_payload; - signed_payload.signed8 = value; - Signed val{SIGNED_8, signed_payload}; - SignedSuffixPayload payload{val, suffixed}; - - return make_signed (payload); + auto text = FFIString::make_ffistring (std::to_string (value)); + auto suffix = FFIString::make_ffistring (suffixed ? "i8" : ""); + return {LitKind::make_integer (), text, suffixed, suffix}; } Literal Literal::make_i16 (std::int16_t value, bool suffixed) { - SignedPayload signed_payload; - signed_payload.signed16 = value; - Signed val{SIGNED_16, signed_payload}; - SignedSuffixPayload payload{val, suffixed}; - - return make_signed (payload); + auto text = FFIString::make_ffistring (std::to_string (value)); + auto suffix = FFIString::make_ffistring (suffixed ? "i16" : ""); + return {LitKind::make_integer (), text, suffixed, suffix}; } Literal Literal::make_i32 (std::int32_t value, bool suffixed) { - SignedPayload signed_payload; - signed_payload.signed32 = value; - Signed val{SIGNED_32, signed_payload}; - SignedSuffixPayload payload = {val, suffixed}; - - return make_signed (payload); + auto text = FFIString::make_ffistring (std::to_string (value)); + auto suffix = FFIString::make_ffistring (suffixed ? "i32" : ""); + return {LitKind::make_integer (), text, suffixed, suffix}; } Literal Literal::make_i64 (std::int64_t value, bool suffixed) { - SignedPayload signed_payload; - signed_payload.signed64 = value; - Signed val{SIGNED_64, signed_payload}; - SignedSuffixPayload payload{val, suffixed}; - - return make_signed (payload); + auto text = FFIString::make_ffistring (std::to_string (value)); + auto suffix = FFIString::make_ffistring (suffixed ? "i64" : ""); + return {LitKind::make_integer (), text, suffixed, suffix}; } Literal Literal::make_string (const std::string &str) { - return make_string (reinterpret_cast (str.c_str ()), - str.length ()); -} - -Literal -Literal::make_string (const unsigned char *str, std::uint64_t len) -{ - unsigned char *data = new unsigned char[len]; - StringPayload str_payload = {data, len}; - std::memcpy (data, str, len); - LiteralPayload payload; - payload.string_payload = str_payload; - return {STRING, payload}; + auto text = FFIString::make_ffistring (str); + auto suffix = FFIString::make_ffistring (""); + return {LitKind::make_str (), text, false, suffix}; } Literal Literal::make_byte_string (const std::vector &vec) { - return make_byte_string (vec.data (), vec.size ()); -} - -Literal -Literal::make_byte_string (const std::uint8_t *bytes, std::uint64_t len) -{ - std::uint8_t *data = new std::uint8_t[len]; - ByteStringPayload bstr_payload = {data, len}; - std::memcpy (data, bytes, len); - LiteralPayload payload; - payload.byte_string_payload = bstr_payload; - return {BYTE_STRING, payload}; + auto text + = FFIString::make_ffistring (std::string (vec.cbegin (), vec.cend ())); + auto suffix = FFIString::make_ffistring (""); + return {LitKind::make_byte_str (), text, false, suffix}; } Literal Literal::make_f32 (float value, bool suffixed) { - Float32Payload f{value, suffixed}; - LiteralPayload payload; - payload.float32_payload = f; - return {FLOAT32, payload}; + auto text = FFIString::make_ffistring (std::to_string (value)); + auto suffix = FFIString::make_ffistring (suffixed ? "f32" : ""); + return {LitKind::make_float (), text, suffixed, suffix}; } Literal Literal::make_f64 (double value, bool suffixed) { - Float64Payload f{value, suffixed}; - LiteralPayload payload; - payload.float64_payload = f; - return {FLOAT64, payload}; + auto text = FFIString::make_ffistring (std::to_string (value)); + auto suffix = FFIString::make_ffistring (suffixed ? "f64" : ""); + return {LitKind::make_float (), text, suffixed, suffix}; } Literal Literal::make_char (std::uint32_t ch) { - LiteralPayload payload; - payload.char_payload = ch; - return {CHAR, payload}; + auto text = FFIString::make_ffistring (std::to_string ((char) ch)); + auto suffix = FFIString::make_ffistring (""); + return {LitKind::make_char (), text, false, suffix}; } Literal Literal::make_usize (std::uint64_t value, bool suffixed) { - UsizePayload p{value, suffixed}; - LiteralPayload payload; - payload.usize_payload = p; - return {USIZE, payload}; + auto text = FFIString::make_ffistring (std::to_string (value)); + auto suffix = FFIString::make_ffistring (suffixed ? "usize" : ""); + return {LitKind::make_integer (), text, suffixed, suffix}; } Literal Literal::make_isize (std::int64_t value, bool suffixed) { - IsizePayload p{value, suffixed}; - LiteralPayload payload; - payload.isize_payload = p; - return {ISIZE, payload}; + auto text = FFIString::make_ffistring (std::to_string (value)); + auto suffix = FFIString::make_ffistring (suffixed ? "isize" : ""); + return {LitKind::make_integer (), text, suffixed, suffix}; +} + +LitKind +LitKind::make_byte () +{ + LitKindPayload payload; + return {BYTE, payload}; +} + +LitKind +LitKind::make_char () +{ + LitKindPayload payload; + return {CHAR, payload}; +} + +LitKind +LitKind::make_integer () +{ + LitKindPayload payload; + return {INTEGER, payload}; +} + +LitKind +LitKind::make_float () +{ + LitKindPayload payload; + return {FLOAT, payload}; +} + +LitKind +LitKind::make_str () +{ + LitKindPayload payload; + return {STR, payload}; +} + +LitKind +LitKind::make_str_raw (std::uint8_t val) +{ + LitKindPayload payload; + payload.str_raw = val; + return {STR_RAW, payload}; +} + +LitKind +LitKind::make_byte_str () +{ + LitKindPayload payload; + return {BYTE_STR, payload}; +} + +LitKind +LitKind::make_byte_str_raw (std::uint8_t val) +{ + LitKindPayload payload; + payload.byte_str_raw = val; + return {BYTE_STR_RAW, payload}; } } // namespace ProcMacro diff --git a/libgrust/libproc_macro/literal.h b/libgrust/libproc_macro/literal.h index f48b534e3f0..fa2df3f62ea 100644 --- a/libgrust/libproc_macro/literal.h +++ b/libgrust/libproc_macro/literal.h @@ -26,183 +26,82 @@ #include #include #include +#include "ffistring.h" namespace ProcMacro { -enum UnsignedTag -{ - UNSIGNED_8, - UNSIGNED_16, - UNSIGNED_32, - UNSIGNED_64, - UNSIGNED_128 -}; -struct Payload128 +enum LitKindTag { - std::uint64_t low; - std::uint64_t high; -}; - -union UnsignedPayload -{ - std::uint8_t unsigned8; - std::uint16_t unsigned16; - std::uint32_t unsigned32; - std::uint64_t unsigned64; - Payload128 unsigned128; -}; - -struct Unsigned -{ - UnsignedTag tag; - UnsignedPayload payload; -}; - -enum SignedTag -{ - SIGNED_8, - SIGNED_16, - SIGNED_32, - SIGNED_64, - SIGNED_128 -}; - -union SignedPayload -{ - std::int8_t signed8; - std::int16_t signed16; - std::int32_t signed32; - std::int64_t signed64; -}; - -struct Signed -{ - SignedTag tag; - SignedPayload payload; -}; - -enum LiteralTag -{ - STRING, - BYTE_STRING, + BYTE, CHAR, - UNSIGNED, - SIGNED, - USIZE, - ISIZE, - FLOAT32, - FLOAT64 + INTEGER, + FLOAT, + STR, + STR_RAW, + BYTE_STR, + BYTE_STR_RAW, }; -struct StringPayload +union LitKindPayload { - unsigned char *data; - std::uint64_t len; + std::uint8_t str_raw; + std::uint8_t byte_str_raw; }; -struct ByteStringPayload +struct LitKind { - std::uint8_t *data; - std::uint64_t size; -}; + LitKindTag tag; + LitKindPayload payload; -struct UnsignedSuffixPayload -{ - Unsigned value; - bool suffix; -}; - -struct SignedSuffixPayload -{ - Signed value; - bool suffix; -}; - -struct UsizePayload -{ - std::uint64_t value; - bool suffix; -}; - -struct IsizePayload -{ - std::int64_t value; - bool suffix; -}; - -struct Float32Payload -{ - float value; - bool suffix; -}; - -struct Float64Payload -{ - double value; - bool suffix; -}; - -union LiteralPayload -{ - StringPayload string_payload; - ByteStringPayload byte_string_payload; - std::uint32_t char_payload; - UnsignedSuffixPayload unsigned_payload; - SignedSuffixPayload signed_payload; - UsizePayload usize_payload; - IsizePayload isize_payload; - Float32Payload float32_payload; - Float64Payload float64_payload; +private: +public: + static LitKind make_byte (); + static LitKind make_char (); + static LitKind make_integer (); + static LitKind make_float (); + static LitKind make_str (); + static LitKind make_str_raw (std::uint8_t val); + static LitKind make_byte_str (); + static LitKind make_byte_str_raw (std::uint8_t val); }; struct Literal { - LiteralTag tag; - LiteralPayload payload; + LitKind kind; + FFIString text; + bool has_suffix; + FFIString suffix; + // TODO: Add span once done in rust interface public: Literal clone () const; - static Literal make_u8 (std::uint8_t value, bool suffixed = false); - static Literal make_u16 (std::uint16_t value, bool suffixed = false); - static Literal make_u32 (std::uint32_t value, bool suffixed = false); - static Literal make_u64 (std::uint64_t value, bool suffixed = false); + static Literal make_literal (const LitKind kind, const std::string &text, + const std::string &suffix = ""); + static Literal make_u8 (std::uint8_t value, bool suffixed = true); + static Literal make_u16 (std::uint16_t value, bool suffixed = true); + static Literal make_u32 (std::uint32_t value, bool suffixed = true); + static Literal make_u64 (std::uint64_t value, bool suffixed = true); - static Literal make_i8 (std::int8_t value, bool suffixed = false); - static Literal make_i16 (std::int16_t value, bool suffixed = false); - static Literal make_i32 (std::int32_t value, bool suffixed = false); - static Literal make_i64 (std::int64_t value, bool suffixed = false); + static Literal make_i8 (std::int8_t value, bool suffixed = true); + static Literal make_i16 (std::int16_t value, bool suffixed = true); + static Literal make_i32 (std::int32_t value, bool suffixed = true); + static Literal make_i64 (std::int64_t value, bool suffixed = true); static Literal make_string (const std::string &str); - static Literal make_string (const unsigned char *str, std::uint64_t len); static Literal make_byte_string (const std::vector &vec); - static Literal make_byte_string (const std::uint8_t *bytes, - std::uint64_t len); static Literal make_f32 (float value, bool suffixed = false); static Literal make_f64 (double value, bool suffixed = false); static Literal make_char (std::uint32_t ch); - static Literal make_usize (std::uint64_t value, bool suffixed = false); - static Literal make_isize (std::int64_t value, bool suffixed = false); + static Literal make_usize (std::uint64_t value, bool suffixed = true); + static Literal make_isize (std::int64_t value, bool suffixed = true); static void drop (Literal *lit); - -private: - static Literal make_unsigned (UnsignedSuffixPayload p); - static Literal make_signed (SignedSuffixPayload p); }; extern "C" { -void -Literal__drop (Literal *lit); - -Literal -Literal__string (const unsigned char *str, std::uint64_t len); - -Literal -Literal__byte_string (const std::uint8_t *bytes, std::uint64_t len); - bool Literal__from_string (const unsigned char *str, std::uint64_t len, Literal *lit);