From a1198a65030478bd4cc4c35018b812c191a53999 Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Thu, 17 Mar 2022 14:23:47 +0000 Subject: [PATCH] [rust] Export cxx.cc symbols This is a version of https://github.com/dtolnay/cxx/pull/1025 backported to the version of cxx which we currently use, plus associated GN changes to trigger that behavior. Purpose of this change: The Rust cxx interop tool produces both Rust and C++ side code for its bindings. It also has fixed C++ code for some of its interop types (e.g. the C++ representation of a Rust string). In most cases, all of this ends up in the same binary, but in debug component builds a test executable may have Rust code which needs to use thse symbols from (for instance) libbase.so. We already previously exported the symbols for dynamically generated bindings code; we now export the symbols for the fixed C++ code too. The patch within this change should be removed if/when https://github.com/dtolnay/cxx/pull/1025 is accepted upstream and we have rolled cxx to include it. Bug: 1287545 Change-Id: I6a0f76fcf6afb36718d5e939c797e7988826bad1 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3531194 Reviewed-by: danakj Commit-Queue: Adrian Taylor Cr-Commit-Position: refs/heads/main@{#982195} NOKEYCHECK=True GitOrigin-RevId: 3b659d0f18bf8f08354a8c35a25b51e542eed659 --- rust/cxx/v1/crate/src/cxx.cc | 317 +++++---- .../0004-Define-exported-cxx-symbols.patch | 669 ++++++++++++++++++ 2 files changed, 855 insertions(+), 131 deletions(-) create mode 100644 rust/cxx/v1/patches/0004-Define-exported-cxx-symbols.patch diff --git a/rust/cxx/v1/crate/src/cxx.cc b/rust/cxx/v1/crate/src/cxx.cc index 686b1a9cdaab..b2d5ef3f32bd 100644 --- a/rust/cxx/v1/crate/src/cxx.cc +++ b/rust/cxx/v1/crate/src/cxx.cc @@ -3,67 +3,87 @@ #include #include +#ifndef CXX_RS_EXPORT +#define CXX_RS_EXPORT +#endif +#ifndef CXX_CPP_EXPORT +#define CXX_CPP_EXPORT +#endif + extern "C" { -void cxxbridge1$cxx_string$init(std::string *s, const std::uint8_t *ptr, - std::size_t len) noexcept { +CXX_RS_EXPORT void cxxbridge1$cxx_string$init(std::string *s, + const std::uint8_t *ptr, + std::size_t len) noexcept { new (s) std::string(reinterpret_cast(ptr), len); } -void cxxbridge1$cxx_string$destroy(std::string *s) noexcept { +CXX_RS_EXPORT void cxxbridge1$cxx_string$destroy(std::string *s) noexcept { using std::string; s->~string(); } -const char *cxxbridge1$cxx_string$data(const std::string &s) noexcept { +CXX_RS_EXPORT const char * +cxxbridge1$cxx_string$data(const std::string &s) noexcept { return s.data(); } -std::size_t cxxbridge1$cxx_string$length(const std::string &s) noexcept { +CXX_RS_EXPORT std::size_t +cxxbridge1$cxx_string$length(const std::string &s) noexcept { return s.length(); } -void cxxbridge1$cxx_string$clear(std::string &s) noexcept { s.clear(); } +CXX_RS_EXPORT void cxxbridge1$cxx_string$clear(std::string &s) noexcept { + s.clear(); +} -void cxxbridge1$cxx_string$reserve_total(std::string &s, - size_t new_cap) noexcept { +CXX_RS_EXPORT void +cxxbridge1$cxx_string$reserve_total(std::string &s, size_t new_cap) noexcept { s.reserve(new_cap); } -void cxxbridge1$cxx_string$push(std::string &s, const std::uint8_t *ptr, - std::size_t len) noexcept { +CXX_RS_EXPORT void cxxbridge1$cxx_string$push(std::string &s, + const std::uint8_t *ptr, + std::size_t len) noexcept { s.append(reinterpret_cast(ptr), len); } // rust::String -void cxxbridge1$string$new(rust::String *self) noexcept; -void cxxbridge1$string$clone(rust::String *self, - const rust::String &other) noexcept; -bool cxxbridge1$string$from_utf8(rust::String *self, const char *ptr, - std::size_t len) noexcept; -bool cxxbridge1$string$from_utf16(rust::String *self, const char16_t *ptr, - std::size_t len) noexcept; -void cxxbridge1$string$drop(rust::String *self) noexcept; -const char *cxxbridge1$string$ptr(const rust::String *self) noexcept; -std::size_t cxxbridge1$string$len(const rust::String *self) noexcept; -std::size_t cxxbridge1$string$capacity(const rust::String *self) noexcept; -void cxxbridge1$string$reserve_additional(rust::String *self, - size_t additional) noexcept; -void cxxbridge1$string$reserve_total(rust::String *self, - size_t new_cap) noexcept; +CXX_RS_EXPORT void cxxbridge1$string$new(rust::String *self) noexcept; +CXX_RS_EXPORT void cxxbridge1$string$clone(rust::String *self, + const rust::String &other) noexcept; +CXX_RS_EXPORT bool cxxbridge1$string$from_utf8(rust::String *self, + const char *ptr, + std::size_t len) noexcept; +CXX_RS_EXPORT bool cxxbridge1$string$from_utf16(rust::String *self, + const char16_t *ptr, + std::size_t len) noexcept; +CXX_RS_EXPORT void cxxbridge1$string$drop(rust::String *self) noexcept; +CXX_RS_EXPORT const char * +cxxbridge1$string$ptr(const rust::String *self) noexcept; +CXX_RS_EXPORT std::size_t +cxxbridge1$string$len(const rust::String *self) noexcept; +CXX_RS_EXPORT std::size_t +cxxbridge1$string$capacity(const rust::String *self) noexcept; +CXX_RS_EXPORT void +cxxbridge1$string$reserve_additional(rust::String *self, + size_t additional) noexcept; +CXX_RS_EXPORT void cxxbridge1$string$reserve_total(rust::String *self, + size_t new_cap) noexcept; // rust::Str -void cxxbridge1$str$new(rust::Str *self) noexcept; -void cxxbridge1$str$ref(rust::Str *self, const rust::String *string) noexcept; -bool cxxbridge1$str$from(rust::Str *self, const char *ptr, - std::size_t len) noexcept; -const char *cxxbridge1$str$ptr(const rust::Str *self) noexcept; -std::size_t cxxbridge1$str$len(const rust::Str *self) noexcept; +CXX_RS_EXPORT void cxxbridge1$str$new(rust::Str *self) noexcept; +CXX_RS_EXPORT void cxxbridge1$str$ref(rust::Str *self, + const rust::String *string) noexcept; +CXX_RS_EXPORT bool cxxbridge1$str$from(rust::Str *self, const char *ptr, + std::size_t len) noexcept; +CXX_RS_EXPORT const char *cxxbridge1$str$ptr(const rust::Str *self) noexcept; +CXX_RS_EXPORT std::size_t cxxbridge1$str$len(const rust::Str *self) noexcept; // rust::Slice -void cxxbridge1$slice$new(void *self, const void *ptr, - std::size_t len) noexcept; -void *cxxbridge1$slice$ptr(const void *self) noexcept; -std::size_t cxxbridge1$slice$len(const void *self) noexcept; +CXX_RS_EXPORT void cxxbridge1$slice$new(void *self, const void *ptr, + std::size_t len) noexcept; +CXX_RS_EXPORT void *cxxbridge1$slice$ptr(const void *self) noexcept; +CXX_RS_EXPORT std::size_t cxxbridge1$slice$len(const void *self) noexcept; } // extern "C" namespace rust { @@ -79,19 +99,20 @@ void panic [[noreturn]] (const char *msg) { #endif } -template void panic [[noreturn]] (const char *msg); +template void panic[[noreturn]] (const char *msg); + -String::String() noexcept { cxxbridge1$string$new(this); } +CXX_CPP_EXPORT String::String() noexcept { cxxbridge1$string$new(this); } -String::String(const String &other) noexcept { +CXX_CPP_EXPORT String::String(const String &other) noexcept { cxxbridge1$string$clone(this, other); } -String::String(String &&other) noexcept : repr(other.repr) { +CXX_CPP_EXPORT String::String(String &&other) noexcept : repr(other.repr) { cxxbridge1$string$new(&other); } -String::~String() noexcept { cxxbridge1$string$drop(this); } +CXX_CPP_EXPORT String::~String() noexcept { cxxbridge1$string$drop(this); } static void initString(String *self, const char *s, std::size_t len) { if (!cxxbridge1$string$from_utf8(self, s, len)) { @@ -105,26 +126,28 @@ static void initString(String *self, const char16_t *s, std::size_t len) { } } -String::String(const std::string &s) { initString(this, s.data(), s.length()); } +CXX_CPP_EXPORT String::String(const std::string &s) { + initString(this, s.data(), s.length()); +} -String::String(const char *s) { +CXX_CPP_EXPORT String::String(const char *s) { assert(s != nullptr); initString(this, s, std::strlen(s)); } -String::String(const char *s, std::size_t len) { +CXX_CPP_EXPORT String::String(const char *s, std::size_t len) { assert(s != nullptr || len == 0); initString(this, s == nullptr && len == 0 ? reinterpret_cast(1) : s, len); } -String::String(const char16_t *s) { +CXX_CPP_EXPORT String::String(const char16_t *s) { assert(s != nullptr); initString(this, s, std::char_traits::length(s)); } -String::String(const char16_t *s, std::size_t len) { +CXX_CPP_EXPORT String::String(const char16_t *s, std::size_t len) { assert(s != nullptr || len == 0); initString(this, s == nullptr && len == 0 ? reinterpret_cast(2) @@ -132,7 +155,7 @@ String::String(const char16_t *s, std::size_t len) { len); } -String &String::operator=(const String &other) &noexcept { +CXX_CPP_EXPORT String &String::operator=(const String &other) &noexcept { if (this != &other) { cxxbridge1$string$drop(this); cxxbridge1$string$clone(this, other); @@ -140,32 +163,32 @@ String &String::operator=(const String &other) &noexcept { return *this; } -String &String::operator=(String &&other) &noexcept { +CXX_CPP_EXPORT String &String::operator=(String &&other) &noexcept { cxxbridge1$string$drop(this); this->repr = other.repr; cxxbridge1$string$new(&other); return *this; } -String::operator std::string() const { +CXX_CPP_EXPORT String::operator std::string() const { return std::string(this->data(), this->size()); } -const char *String::data() const noexcept { +CXX_CPP_EXPORT const char *String::data() const noexcept { return cxxbridge1$string$ptr(this); } -std::size_t String::size() const noexcept { +CXX_CPP_EXPORT std::size_t String::size() const noexcept { return cxxbridge1$string$len(this); } -std::size_t String::length() const noexcept { +CXX_CPP_EXPORT std::size_t String::length() const noexcept { return cxxbridge1$string$len(this); } -bool String::empty() const noexcept { return this->size() == 0; } +CXX_CPP_EXPORT bool String::empty() const noexcept { return this->size() == 0; } -const char *String::c_str() noexcept { +CXX_CPP_EXPORT const char *String::c_str() noexcept { auto len = this->length(); cxxbridge1$string$reserve_additional(this, 1); auto ptr = this->data(); @@ -173,128 +196,151 @@ const char *String::c_str() noexcept { return ptr; } -std::size_t String::capacity() const noexcept { +CXX_CPP_EXPORT std::size_t String::capacity() const noexcept { return cxxbridge1$string$capacity(this); } -void String::reserve(std::size_t new_cap) noexcept { +CXX_CPP_EXPORT void String::reserve(std::size_t new_cap) noexcept { cxxbridge1$string$reserve_total(this, new_cap); } -String::iterator String::begin() noexcept { +CXX_CPP_EXPORT String::iterator String::begin() noexcept { return const_cast(this->data()); } -String::iterator String::end() noexcept { +CXX_CPP_EXPORT String::iterator String::end() noexcept { return const_cast(this->data()) + this->size(); } -String::const_iterator String::begin() const noexcept { return this->cbegin(); } +CXX_CPP_EXPORT String::const_iterator String::begin() const noexcept { + return this->cbegin(); +} -String::const_iterator String::end() const noexcept { return this->cend(); } +CXX_CPP_EXPORT String::const_iterator String::end() const noexcept { + return this->cend(); +} -String::const_iterator String::cbegin() const noexcept { return this->data(); } +CXX_CPP_EXPORT String::const_iterator String::cbegin() const noexcept { + return this->data(); +} -String::const_iterator String::cend() const noexcept { +CXX_CPP_EXPORT String::const_iterator String::cend() const noexcept { return this->data() + this->size(); } -bool String::operator==(const String &rhs) const noexcept { +CXX_CPP_EXPORT bool String::operator==(const String &rhs) const noexcept { return rust::Str(*this) == rust::Str(rhs); } -bool String::operator!=(const String &rhs) const noexcept { +CXX_CPP_EXPORT bool String::operator!=(const String &rhs) const noexcept { return rust::Str(*this) != rust::Str(rhs); } -bool String::operator<(const String &rhs) const noexcept { +CXX_CPP_EXPORT bool String::operator<(const String &rhs) const noexcept { return rust::Str(*this) < rust::Str(rhs); } -bool String::operator<=(const String &rhs) const noexcept { +CXX_CPP_EXPORT bool String::operator<=(const String &rhs) const noexcept { return rust::Str(*this) <= rust::Str(rhs); } -bool String::operator>(const String &rhs) const noexcept { +CXX_CPP_EXPORT bool String::operator>(const String &rhs) const noexcept { return rust::Str(*this) > rust::Str(rhs); } -bool String::operator>=(const String &rhs) const noexcept { +CXX_CPP_EXPORT bool String::operator>=(const String &rhs) const noexcept { return rust::Str(*this) >= rust::Str(rhs); } -void String::swap(String &rhs) noexcept { +CXX_CPP_EXPORT void String::swap(String &rhs) noexcept { using std::swap; swap(this->repr, rhs.repr); } -String::String(unsafe_bitcopy_t, const String &bits) noexcept +CXX_CPP_EXPORT String::String(unsafe_bitcopy_t, const String &bits) noexcept : repr(bits.repr) {} -std::ostream &operator<<(std::ostream &os, const String &s) { +CXX_CPP_EXPORT std::ostream &operator<<(std::ostream &os, const String &s) { os.write(s.data(), s.size()); return os; } -Str::Str() noexcept { cxxbridge1$str$new(this); } +CXX_CPP_EXPORT Str::Str() noexcept { cxxbridge1$str$new(this); } -Str::Str(const String &s) noexcept { cxxbridge1$str$ref(this, &s); } +CXX_CPP_EXPORT Str::Str(const String &s) noexcept { + cxxbridge1$str$ref(this, &s); +} -static void initStr(Str *self, const char *ptr, std::size_t len) { +CXX_CPP_EXPORT static void initStr(Str *self, const char *ptr, + std::size_t len) { if (!cxxbridge1$str$from(self, ptr, len)) { panic("data for rust::Str is not utf-8"); } } -Str::Str(const std::string &s) { initStr(this, s.data(), s.length()); } +CXX_CPP_EXPORT Str::Str(const std::string &s) { + initStr(this, s.data(), s.length()); +} -Str::Str(const char *s) { +CXX_CPP_EXPORT Str::Str(const char *s) { assert(s != nullptr); initStr(this, s, std::strlen(s)); } -Str::Str(const char *s, std::size_t len) { +CXX_CPP_EXPORT Str::Str(const char *s, std::size_t len) { assert(s != nullptr || len == 0); initStr(this, s == nullptr && len == 0 ? reinterpret_cast(1) : s, len); } -Str::operator std::string() const { +CXX_CPP_EXPORT Str::operator std::string() const { return std::string(this->data(), this->size()); } -const char *Str::data() const noexcept { return cxxbridge1$str$ptr(this); } +CXX_CPP_EXPORT const char *Str::data() const noexcept { + return cxxbridge1$str$ptr(this); +} -std::size_t Str::size() const noexcept { return cxxbridge1$str$len(this); } +CXX_CPP_EXPORT std::size_t Str::size() const noexcept { + return cxxbridge1$str$len(this); +} -std::size_t Str::length() const noexcept { return this->size(); } +CXX_CPP_EXPORT std::size_t Str::length() const noexcept { return this->size(); } -bool Str::empty() const noexcept { return this->size() == 0; } +CXX_CPP_EXPORT bool Str::empty() const noexcept { return this->size() == 0; } -Str::const_iterator Str::begin() const noexcept { return this->cbegin(); } +CXX_CPP_EXPORT Str::const_iterator Str::begin() const noexcept { + return this->cbegin(); +} -Str::const_iterator Str::end() const noexcept { return this->cend(); } +CXX_CPP_EXPORT Str::const_iterator Str::end() const noexcept { + return this->cend(); +} -Str::const_iterator Str::cbegin() const noexcept { return this->data(); } +CXX_CPP_EXPORT Str::const_iterator Str::cbegin() const noexcept { + return this->data(); +} -Str::const_iterator Str::cend() const noexcept { +CXX_CPP_EXPORT Str::const_iterator Str::cend() const noexcept { return this->data() + this->size(); } -bool Str::operator==(const Str &rhs) const noexcept { +CXX_CPP_EXPORT bool Str::operator==(const Str &rhs) const noexcept { return this->size() == rhs.size() && std::equal(this->begin(), this->end(), rhs.begin()); } -bool Str::operator!=(const Str &rhs) const noexcept { return !(*this == rhs); } +CXX_CPP_EXPORT bool Str::operator!=(const Str &rhs) const noexcept { + return !(*this == rhs); +} -bool Str::operator<(const Str &rhs) const noexcept { +CXX_CPP_EXPORT bool Str::operator<(const Str &rhs) const noexcept { return std::lexicographical_compare(this->begin(), this->end(), rhs.begin(), rhs.end()); } -bool Str::operator<=(const Str &rhs) const noexcept { +CXX_CPP_EXPORT bool Str::operator<=(const Str &rhs) const noexcept { // std::mismatch(this->begin(), this->end(), rhs.begin(), rhs.end()), except // without Undefined Behavior on C++11 if rhs is shorter than *this. const_iterator liter = this->begin(), lend = this->end(), riter = rhs.begin(), @@ -311,27 +357,34 @@ bool Str::operator<=(const Str &rhs) const noexcept { } } -bool Str::operator>(const Str &rhs) const noexcept { return rhs < *this; } +CXX_CPP_EXPORT bool Str::operator>(const Str &rhs) const noexcept { + return rhs < *this; +} -bool Str::operator>=(const Str &rhs) const noexcept { return rhs <= *this; } +CXX_CPP_EXPORT bool Str::operator>=(const Str &rhs) const noexcept { + return rhs <= *this; +} -void Str::swap(Str &rhs) noexcept { +CXX_CPP_EXPORT void Str::swap(Str &rhs) noexcept { using std::swap; swap(this->repr, rhs.repr); } -std::ostream &operator<<(std::ostream &os, const Str &s) { +CXX_CPP_EXPORT std::ostream &operator<<(std::ostream &os, const Str &s) { os.write(s.data(), s.size()); return os; } -void sliceInit(void *self, const void *ptr, std::size_t len) noexcept { +CXX_CPP_EXPORT void sliceInit(void *self, const void *ptr, + std::size_t len) noexcept { cxxbridge1$slice$new(self, ptr, len); } -void *slicePtr(const void *self) noexcept { return cxxbridge1$slice$ptr(self); } +CXX_CPP_EXPORT void *slicePtr(const void *self) noexcept { + return cxxbridge1$slice$ptr(self); +} -std::size_t sliceLen(const void *self) noexcept { +CXX_CPP_EXPORT std::size_t sliceLen(const void *self) noexcept { return cxxbridge1$slice$len(self); } @@ -402,7 +455,8 @@ static const char *errorCopy(const char *ptr, std::size_t len) { } extern "C" { -const char *cxxbridge1$error(const char *ptr, std::size_t len) noexcept { +CXX_RS_EXPORT const char *cxxbridge1$error(const char *ptr, + std::size_t len) noexcept { return errorCopy(ptr, len); } } // extern "C" @@ -479,23 +533,24 @@ void destroy(T *ptr) { } // namespace extern "C" { -void cxxbridge1$unique_ptr$std$string$null( +CXX_RS_EXPORT void cxxbridge1$unique_ptr$std$string$null( std::unique_ptr *ptr) noexcept { new (ptr) std::unique_ptr(); } -void cxxbridge1$unique_ptr$std$string$raw(std::unique_ptr *ptr, - std::string *raw) noexcept { +CXX_RS_EXPORT void +cxxbridge1$unique_ptr$std$string$raw(std::unique_ptr *ptr, + std::string *raw) noexcept { new (ptr) std::unique_ptr(raw); } -const std::string *cxxbridge1$unique_ptr$std$string$get( +CXX_RS_EXPORT const std::string *cxxbridge1$unique_ptr$std$string$get( const std::unique_ptr &ptr) noexcept { return ptr.get(); } -std::string *cxxbridge1$unique_ptr$std$string$release( +CXX_RS_EXPORT std::string *cxxbridge1$unique_ptr$std$string$release( std::unique_ptr &ptr) noexcept { return ptr.release(); } -void cxxbridge1$unique_ptr$std$string$drop( +CXX_RS_EXPORT void cxxbridge1$unique_ptr$std$string$drop( std::unique_ptr *ptr) noexcept { ptr->~unique_ptr(); } @@ -510,65 +565,65 @@ static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *), } // namespace #define STD_VECTOR_OPS(RUST_TYPE, CXX_TYPE) \ - std::size_t cxxbridge1$std$vector$##RUST_TYPE##$size( \ + CXX_RS_EXPORT std::size_t cxxbridge1$std$vector$##RUST_TYPE##$size( \ const std::vector &s) noexcept { \ return s.size(); \ } \ - CXX_TYPE *cxxbridge1$std$vector$##RUST_TYPE##$get_unchecked( \ + CXX_RS_EXPORT CXX_TYPE *cxxbridge1$std$vector$##RUST_TYPE##$get_unchecked( \ std::vector *s, std::size_t pos) noexcept { \ return &(*s)[pos]; \ } \ - void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$null( \ + CXX_RS_EXPORT void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$null( \ std::unique_ptr> *ptr) noexcept { \ new (ptr) std::unique_ptr>(); \ } \ - void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$raw( \ + CXX_RS_EXPORT void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$raw( \ std::unique_ptr> *ptr, \ std::vector *raw) noexcept { \ new (ptr) std::unique_ptr>(raw); \ } \ - const std::vector \ + CXX_RS_EXPORT const std::vector \ *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$get( \ const std::unique_ptr> &ptr) noexcept { \ return ptr.get(); \ } \ - std::vector \ + CXX_RS_EXPORT std::vector \ *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$release( \ std::unique_ptr> &ptr) noexcept { \ return ptr.release(); \ } \ - void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$drop( \ + CXX_RS_EXPORT void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$drop( \ std::unique_ptr> *ptr) noexcept { \ ptr->~unique_ptr(); \ } #define STD_VECTOR_TRIVIAL_OPS(RUST_TYPE, CXX_TYPE) \ - void cxxbridge1$std$vector$##RUST_TYPE##$push_back( \ + CXX_RS_EXPORT void cxxbridge1$std$vector$##RUST_TYPE##$push_back( \ std::vector *v, CXX_TYPE *value) noexcept { \ v->push_back(std::move(*value)); \ destroy(value); \ } \ - void cxxbridge1$std$vector$##RUST_TYPE##$pop_back(std::vector *v, \ - CXX_TYPE *out) noexcept { \ + CXX_RS_EXPORT void cxxbridge1$std$vector$##RUST_TYPE##$pop_back( \ + std::vector *v, CXX_TYPE *out) noexcept { \ new (out) CXX_TYPE(std::move(v->back())); \ v->pop_back(); \ } #define RUST_VEC_EXTERNS(RUST_TYPE, CXX_TYPE) \ - void cxxbridge1$rust_vec$##RUST_TYPE##$new( \ + CXX_RS_EXPORT void cxxbridge1$rust_vec$##RUST_TYPE##$new( \ rust::Vec *ptr) noexcept; \ - void cxxbridge1$rust_vec$##RUST_TYPE##$drop( \ + CXX_RS_EXPORT void cxxbridge1$rust_vec$##RUST_TYPE##$drop( \ rust::Vec *ptr) noexcept; \ - std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$len( \ + CXX_RS_EXPORT std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$len( \ const rust::Vec *ptr) noexcept; \ - std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$capacity( \ + CXX_RS_EXPORT std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$capacity( \ const rust::Vec *ptr) noexcept; \ - const CXX_TYPE *cxxbridge1$rust_vec$##RUST_TYPE##$data( \ + CXX_RS_EXPORT const CXX_TYPE *cxxbridge1$rust_vec$##RUST_TYPE##$data( \ const rust::Vec *ptr) noexcept; \ - void cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total( \ + CXX_RS_EXPORT void cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total( \ rust::Vec *ptr, std::size_t new_cap) noexcept; \ - void cxxbridge1$rust_vec$##RUST_TYPE##$set_len(rust::Vec *ptr, \ - std::size_t len) noexcept; + CXX_RS_EXPORT void cxxbridge1$rust_vec$##RUST_TYPE##$set_len( \ + rust::Vec *ptr, std::size_t len) noexcept; #define RUST_VEC_OPS(RUST_TYPE, CXX_TYPE) \ template <> \ @@ -603,52 +658,52 @@ static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *), #define SHARED_PTR_OPS(RUST_TYPE, CXX_TYPE) \ static_assert(sizeof(std::shared_ptr) == 2 * sizeof(void *), ""); \ static_assert(alignof(std::shared_ptr) == alignof(void *), ""); \ - void cxxbridge1$std$shared_ptr$##RUST_TYPE##$null( \ + CXX_RS_EXPORT void cxxbridge1$std$shared_ptr$##RUST_TYPE##$null( \ std::shared_ptr *ptr) noexcept { \ new (ptr) std::shared_ptr(); \ } \ - CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$uninit( \ + CXX_RS_EXPORT CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$uninit( \ std::shared_ptr *ptr) noexcept { \ CXX_TYPE *uninit = \ reinterpret_cast(new rust::MaybeUninit); \ new (ptr) std::shared_ptr(uninit); \ return uninit; \ } \ - void cxxbridge1$std$shared_ptr$##RUST_TYPE##$clone( \ + CXX_RS_EXPORT void cxxbridge1$std$shared_ptr$##RUST_TYPE##$clone( \ const std::shared_ptr &self, \ std::shared_ptr *ptr) noexcept { \ new (ptr) std::shared_ptr(self); \ } \ - const CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$get( \ + CXX_RS_EXPORT const CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$get( \ const std::shared_ptr &self) noexcept { \ return self.get(); \ } \ - void cxxbridge1$std$shared_ptr$##RUST_TYPE##$drop( \ + CXX_RS_EXPORT void cxxbridge1$std$shared_ptr$##RUST_TYPE##$drop( \ const std::shared_ptr *self) noexcept { \ self->~shared_ptr(); \ } \ static_assert(sizeof(std::weak_ptr) == 2 * sizeof(void *), ""); \ static_assert(alignof(std::weak_ptr) == alignof(void *), ""); \ - void cxxbridge1$std$weak_ptr$##RUST_TYPE##$null( \ + CXX_RS_EXPORT void cxxbridge1$std$weak_ptr$##RUST_TYPE##$null( \ std::weak_ptr *ptr) noexcept { \ new (ptr) std::weak_ptr(); \ } \ - void cxxbridge1$std$weak_ptr$##RUST_TYPE##$clone( \ + CXX_RS_EXPORT void cxxbridge1$std$weak_ptr$##RUST_TYPE##$clone( \ const std::weak_ptr &self, \ std::weak_ptr *ptr) noexcept { \ new (ptr) std::weak_ptr(self); \ } \ - void cxxbridge1$std$weak_ptr$##RUST_TYPE##$downgrade( \ + CXX_RS_EXPORT void cxxbridge1$std$weak_ptr$##RUST_TYPE##$downgrade( \ const std::shared_ptr &shared, \ std::weak_ptr *weak) noexcept { \ new (weak) std::weak_ptr(shared); \ } \ - void cxxbridge1$std$weak_ptr$##RUST_TYPE##$upgrade( \ + CXX_RS_EXPORT void cxxbridge1$std$weak_ptr$##RUST_TYPE##$upgrade( \ const std::weak_ptr &weak, \ std::shared_ptr *shared) noexcept { \ new (shared) std::shared_ptr(weak.lock()); \ } \ - void cxxbridge1$std$weak_ptr$##RUST_TYPE##$drop( \ + CXX_RS_EXPORT void cxxbridge1$std$weak_ptr$##RUST_TYPE##$drop( \ const std::weak_ptr *self) noexcept { \ self->~weak_ptr(); \ } diff --git a/rust/cxx/v1/patches/0004-Define-exported-cxx-symbols.patch b/rust/cxx/v1/patches/0004-Define-exported-cxx-symbols.patch new file mode 100644 index 000000000000..fb2ddfe017bd --- /dev/null +++ b/rust/cxx/v1/patches/0004-Define-exported-cxx-symbols.patch @@ -0,0 +1,669 @@ +From b06f18236b6da3233f9bed87531232a68eeac3ef Mon Sep 17 00:00:00 2001 +From: Adrian Taylor +Date: Wed, 16 Mar 2022 13:58:58 -0700 +Subject: [PATCH 1/2] Define exported cxx symbols. + +This is a version of +https://github.com/dtolnay/cxx/pull/1025 +backported to the version of cxx which we currently use. + +Change-Id: I6a0f76fcf6afb36718d5e939c797e7988826bad1 +--- + third_party/rust/cxx/v1/crate/src/cxx.cc | 314 +++++++++++++---------- + 1 file changed, 184 insertions(+), 130 deletions(-) + +diff --git a/third_party/rust/cxx/v1/crate/src/cxx.cc b/third_party/rust/cxx/v1/crate/src/cxx.cc +index 686b1a9cdaab0..c22ba100733f1 100644 +--- a/third_party/rust/cxx/v1/crate/src/cxx.cc ++++ b/third_party/rust/cxx/v1/crate/src/cxx.cc +@@ -3,67 +3,86 @@ + #include + #include + ++#ifndef CXX_RS_EXPORT ++#define CXX_RS_EXPORT ++#endif ++#ifndef CXX_CPP_EXPORT ++#define CXX_CPP_EXPORT ++#endif ++ + extern "C" { +-void cxxbridge1$cxx_string$init(std::string *s, const std::uint8_t *ptr, +- std::size_t len) noexcept { ++CXX_RS_EXPORT void cxxbridge1$cxx_string$init(std::string *s, ++ const std::uint8_t *ptr, ++ std::size_t len) noexcept { + new (s) std::string(reinterpret_cast(ptr), len); + } + +-void cxxbridge1$cxx_string$destroy(std::string *s) noexcept { ++CXX_RS_EXPORT void cxxbridge1$cxx_string$destroy(std::string *s) noexcept { + using std::string; + s->~string(); + } + +-const char *cxxbridge1$cxx_string$data(const std::string &s) noexcept { ++CXX_RS_EXPORT const char * ++cxxbridge1$cxx_string$data(const std::string &s) noexcept { + return s.data(); + } + +-std::size_t cxxbridge1$cxx_string$length(const std::string &s) noexcept { ++CXX_RS_EXPORT std::size_t ++cxxbridge1$cxx_string$length(const std::string &s) noexcept { + return s.length(); + } + +-void cxxbridge1$cxx_string$clear(std::string &s) noexcept { s.clear(); } ++CXX_RS_EXPORT void cxxbridge1$cxx_string$clear(std::string &s) noexcept { ++ s.clear(); ++} + +-void cxxbridge1$cxx_string$reserve_total(std::string &s, +- size_t new_cap) noexcept { ++CXX_RS_EXPORT void ++cxxbridge1$cxx_string$reserve_total(std::string &s, size_t new_cap) noexcept { + s.reserve(new_cap); + } + +-void cxxbridge1$cxx_string$push(std::string &s, const std::uint8_t *ptr, +- std::size_t len) noexcept { ++CXX_RS_EXPORT void cxxbridge1$cxx_string$push(std::string &s, ++ const std::uint8_t *ptr, ++ std::size_t len) noexcept { + s.append(reinterpret_cast(ptr), len); + } + + // rust::String +-void cxxbridge1$string$new(rust::String *self) noexcept; +-void cxxbridge1$string$clone(rust::String *self, +- const rust::String &other) noexcept; +-bool cxxbridge1$string$from_utf8(rust::String *self, const char *ptr, +- std::size_t len) noexcept; +-bool cxxbridge1$string$from_utf16(rust::String *self, const char16_t *ptr, ++CXX_RS_EXPORT void cxxbridge1$string$new(rust::String *self) noexcept; ++CXX_RS_EXPORT void cxxbridge1$string$clone(rust::String *self, ++ const rust::String &other) noexcept; ++CXX_RS_EXPORT bool cxxbridge1$string$from_utf8(rust::String *self, ++ const char *ptr, ++ std::size_t len) noexcept; ++CXX_RS_EXPORT bool cxxbridge1$string$from_utf16(rust::String *self, const char16_t *ptr, + std::size_t len) noexcept; +-void cxxbridge1$string$drop(rust::String *self) noexcept; +-const char *cxxbridge1$string$ptr(const rust::String *self) noexcept; +-std::size_t cxxbridge1$string$len(const rust::String *self) noexcept; +-std::size_t cxxbridge1$string$capacity(const rust::String *self) noexcept; +-void cxxbridge1$string$reserve_additional(rust::String *self, +- size_t additional) noexcept; +-void cxxbridge1$string$reserve_total(rust::String *self, +- size_t new_cap) noexcept; ++CXX_RS_EXPORT void cxxbridge1$string$drop(rust::String *self) noexcept; ++CXX_RS_EXPORT const char * ++cxxbridge1$string$ptr(const rust::String *self) noexcept; ++CXX_RS_EXPORT std::size_t ++cxxbridge1$string$len(const rust::String *self) noexcept; ++CXX_RS_EXPORT std::size_t ++cxxbridge1$string$capacity(const rust::String *self) noexcept; ++CXX_RS_EXPORT void ++cxxbridge1$string$reserve_additional(rust::String *self, ++ size_t additional) noexcept; ++CXX_RS_EXPORT void cxxbridge1$string$reserve_total(rust::String *self, ++ size_t new_cap) noexcept; + + // rust::Str +-void cxxbridge1$str$new(rust::Str *self) noexcept; +-void cxxbridge1$str$ref(rust::Str *self, const rust::String *string) noexcept; +-bool cxxbridge1$str$from(rust::Str *self, const char *ptr, +- std::size_t len) noexcept; +-const char *cxxbridge1$str$ptr(const rust::Str *self) noexcept; +-std::size_t cxxbridge1$str$len(const rust::Str *self) noexcept; ++CXX_RS_EXPORT void cxxbridge1$str$new(rust::Str *self) noexcept; ++CXX_RS_EXPORT void cxxbridge1$str$ref(rust::Str *self, ++ const rust::String *string) noexcept; ++CXX_RS_EXPORT bool cxxbridge1$str$from(rust::Str *self, const char *ptr, ++ std::size_t len) noexcept; ++CXX_RS_EXPORT const char *cxxbridge1$str$ptr(const rust::Str *self) noexcept; ++CXX_RS_EXPORT std::size_t cxxbridge1$str$len(const rust::Str *self) noexcept; + + // rust::Slice +-void cxxbridge1$slice$new(void *self, const void *ptr, +- std::size_t len) noexcept; +-void *cxxbridge1$slice$ptr(const void *self) noexcept; +-std::size_t cxxbridge1$slice$len(const void *self) noexcept; ++CXX_RS_EXPORT void cxxbridge1$slice$new(void *self, const void *ptr, ++ std::size_t len) noexcept; ++CXX_RS_EXPORT void *cxxbridge1$slice$ptr(const void *self) noexcept; ++CXX_RS_EXPORT std::size_t cxxbridge1$slice$len(const void *self) noexcept; + } // extern "C" + + namespace rust { +@@ -79,19 +98,20 @@ void panic [[noreturn]] (const char *msg) { + #endif + } + +-template void panic [[noreturn]] (const char *msg); ++template void panic[[noreturn]] (const char *msg); ++ + +-String::String() noexcept { cxxbridge1$string$new(this); } ++CXX_CPP_EXPORT String::String() noexcept { cxxbridge1$string$new(this); } + +-String::String(const String &other) noexcept { ++CXX_CPP_EXPORT String::String(const String &other) noexcept { + cxxbridge1$string$clone(this, other); + } + +-String::String(String &&other) noexcept : repr(other.repr) { ++CXX_CPP_EXPORT String::String(String &&other) noexcept : repr(other.repr) { + cxxbridge1$string$new(&other); + } + +-String::~String() noexcept { cxxbridge1$string$drop(this); } ++CXX_CPP_EXPORT String::~String() noexcept { cxxbridge1$string$drop(this); } + + static void initString(String *self, const char *s, std::size_t len) { + if (!cxxbridge1$string$from_utf8(self, s, len)) { +@@ -105,26 +125,28 @@ static void initString(String *self, const char16_t *s, std::size_t len) { + } + } + +-String::String(const std::string &s) { initString(this, s.data(), s.length()); } ++CXX_CPP_EXPORT String::String(const std::string &s) { ++ initString(this, s.data(), s.length()); ++} + +-String::String(const char *s) { ++CXX_CPP_EXPORT String::String(const char *s) { + assert(s != nullptr); + initString(this, s, std::strlen(s)); + } + +-String::String(const char *s, std::size_t len) { ++CXX_CPP_EXPORT String::String(const char *s, std::size_t len) { + assert(s != nullptr || len == 0); + initString(this, + s == nullptr && len == 0 ? reinterpret_cast(1) : s, + len); + } + +-String::String(const char16_t *s) { ++CXX_CPP_EXPORT String::String(const char16_t *s) { + assert(s != nullptr); + initString(this, s, std::char_traits::length(s)); + } + +-String::String(const char16_t *s, std::size_t len) { ++CXX_CPP_EXPORT String::String(const char16_t *s, std::size_t len) { + assert(s != nullptr || len == 0); + initString(this, + s == nullptr && len == 0 ? reinterpret_cast(2) +@@ -132,7 +154,7 @@ String::String(const char16_t *s, std::size_t len) { + len); + } + +-String &String::operator=(const String &other) &noexcept { ++CXX_CPP_EXPORT String &String::operator=(const String &other) &noexcept { + if (this != &other) { + cxxbridge1$string$drop(this); + cxxbridge1$string$clone(this, other); +@@ -140,32 +162,32 @@ String &String::operator=(const String &other) &noexcept { + return *this; + } + +-String &String::operator=(String &&other) &noexcept { ++CXX_CPP_EXPORT String &String::operator=(String &&other) &noexcept { + cxxbridge1$string$drop(this); + this->repr = other.repr; + cxxbridge1$string$new(&other); + return *this; + } + +-String::operator std::string() const { ++CXX_CPP_EXPORT String::operator std::string() const { + return std::string(this->data(), this->size()); + } + +-const char *String::data() const noexcept { ++CXX_CPP_EXPORT const char *String::data() const noexcept { + return cxxbridge1$string$ptr(this); + } + +-std::size_t String::size() const noexcept { ++CXX_CPP_EXPORT std::size_t String::size() const noexcept { + return cxxbridge1$string$len(this); + } + +-std::size_t String::length() const noexcept { ++CXX_CPP_EXPORT std::size_t String::length() const noexcept { + return cxxbridge1$string$len(this); + } + +-bool String::empty() const noexcept { return this->size() == 0; } ++CXX_CPP_EXPORT bool String::empty() const noexcept { return this->size() == 0; } + +-const char *String::c_str() noexcept { ++CXX_CPP_EXPORT const char *String::c_str() noexcept { + auto len = this->length(); + cxxbridge1$string$reserve_additional(this, 1); + auto ptr = this->data(); +@@ -173,128 +195,151 @@ const char *String::c_str() noexcept { + return ptr; + } + +-std::size_t String::capacity() const noexcept { ++CXX_CPP_EXPORT std::size_t String::capacity() const noexcept { + return cxxbridge1$string$capacity(this); + } + +-void String::reserve(std::size_t new_cap) noexcept { ++CXX_CPP_EXPORT void String::reserve(std::size_t new_cap) noexcept { + cxxbridge1$string$reserve_total(this, new_cap); + } + +-String::iterator String::begin() noexcept { ++CXX_CPP_EXPORT String::iterator String::begin() noexcept { + return const_cast(this->data()); + } + +-String::iterator String::end() noexcept { ++CXX_CPP_EXPORT String::iterator String::end() noexcept { + return const_cast(this->data()) + this->size(); + } + +-String::const_iterator String::begin() const noexcept { return this->cbegin(); } ++CXX_CPP_EXPORT String::const_iterator String::begin() const noexcept { ++ return this->cbegin(); ++} + +-String::const_iterator String::end() const noexcept { return this->cend(); } ++CXX_CPP_EXPORT String::const_iterator String::end() const noexcept { ++ return this->cend(); ++} + +-String::const_iterator String::cbegin() const noexcept { return this->data(); } ++CXX_CPP_EXPORT String::const_iterator String::cbegin() const noexcept { ++ return this->data(); ++} + +-String::const_iterator String::cend() const noexcept { ++CXX_CPP_EXPORT String::const_iterator String::cend() const noexcept { + return this->data() + this->size(); + } + +-bool String::operator==(const String &rhs) const noexcept { ++CXX_CPP_EXPORT bool String::operator==(const String &rhs) const noexcept { + return rust::Str(*this) == rust::Str(rhs); + } + +-bool String::operator!=(const String &rhs) const noexcept { ++CXX_CPP_EXPORT bool String::operator!=(const String &rhs) const noexcept { + return rust::Str(*this) != rust::Str(rhs); + } + +-bool String::operator<(const String &rhs) const noexcept { ++CXX_CPP_EXPORT bool String::operator<(const String &rhs) const noexcept { + return rust::Str(*this) < rust::Str(rhs); + } + +-bool String::operator<=(const String &rhs) const noexcept { ++CXX_CPP_EXPORT bool String::operator<=(const String &rhs) const noexcept { + return rust::Str(*this) <= rust::Str(rhs); + } + +-bool String::operator>(const String &rhs) const noexcept { ++CXX_CPP_EXPORT bool String::operator>(const String &rhs) const noexcept { + return rust::Str(*this) > rust::Str(rhs); + } + +-bool String::operator>=(const String &rhs) const noexcept { ++CXX_CPP_EXPORT bool String::operator>=(const String &rhs) const noexcept { + return rust::Str(*this) >= rust::Str(rhs); + } + +-void String::swap(String &rhs) noexcept { ++CXX_CPP_EXPORT void String::swap(String &rhs) noexcept { + using std::swap; + swap(this->repr, rhs.repr); + } + +-String::String(unsafe_bitcopy_t, const String &bits) noexcept ++CXX_CPP_EXPORT String::String(unsafe_bitcopy_t, const String &bits) noexcept + : repr(bits.repr) {} + +-std::ostream &operator<<(std::ostream &os, const String &s) { ++CXX_CPP_EXPORT std::ostream &operator<<(std::ostream &os, const String &s) { + os.write(s.data(), s.size()); + return os; + } + +-Str::Str() noexcept { cxxbridge1$str$new(this); } ++CXX_CPP_EXPORT Str::Str() noexcept { cxxbridge1$str$new(this); } + +-Str::Str(const String &s) noexcept { cxxbridge1$str$ref(this, &s); } ++CXX_CPP_EXPORT Str::Str(const String &s) noexcept { ++ cxxbridge1$str$ref(this, &s); ++} + +-static void initStr(Str *self, const char *ptr, std::size_t len) { ++CXX_CPP_EXPORT static void initStr(Str *self, const char *ptr, ++ std::size_t len) { + if (!cxxbridge1$str$from(self, ptr, len)) { + panic("data for rust::Str is not utf-8"); + } + } + +-Str::Str(const std::string &s) { initStr(this, s.data(), s.length()); } ++CXX_CPP_EXPORT Str::Str(const std::string &s) { ++ initStr(this, s.data(), s.length()); ++} + +-Str::Str(const char *s) { ++CXX_CPP_EXPORT Str::Str(const char *s) { + assert(s != nullptr); + initStr(this, s, std::strlen(s)); + } + +-Str::Str(const char *s, std::size_t len) { ++CXX_CPP_EXPORT Str::Str(const char *s, std::size_t len) { + assert(s != nullptr || len == 0); + initStr(this, + s == nullptr && len == 0 ? reinterpret_cast(1) : s, + len); + } + +-Str::operator std::string() const { ++CXX_CPP_EXPORT Str::operator std::string() const { + return std::string(this->data(), this->size()); + } + +-const char *Str::data() const noexcept { return cxxbridge1$str$ptr(this); } ++CXX_CPP_EXPORT const char *Str::data() const noexcept { ++ return cxxbridge1$str$ptr(this); ++} + +-std::size_t Str::size() const noexcept { return cxxbridge1$str$len(this); } ++CXX_CPP_EXPORT std::size_t Str::size() const noexcept { ++ return cxxbridge1$str$len(this); ++} + +-std::size_t Str::length() const noexcept { return this->size(); } ++CXX_CPP_EXPORT std::size_t Str::length() const noexcept { return this->size(); } + +-bool Str::empty() const noexcept { return this->size() == 0; } ++CXX_CPP_EXPORT bool Str::empty() const noexcept { return this->size() == 0; } + +-Str::const_iterator Str::begin() const noexcept { return this->cbegin(); } ++CXX_CPP_EXPORT Str::const_iterator Str::begin() const noexcept { ++ return this->cbegin(); ++} + +-Str::const_iterator Str::end() const noexcept { return this->cend(); } ++CXX_CPP_EXPORT Str::const_iterator Str::end() const noexcept { ++ return this->cend(); ++} + +-Str::const_iterator Str::cbegin() const noexcept { return this->data(); } ++CXX_CPP_EXPORT Str::const_iterator Str::cbegin() const noexcept { ++ return this->data(); ++} + +-Str::const_iterator Str::cend() const noexcept { ++CXX_CPP_EXPORT Str::const_iterator Str::cend() const noexcept { + return this->data() + this->size(); + } + +-bool Str::operator==(const Str &rhs) const noexcept { ++CXX_CPP_EXPORT bool Str::operator==(const Str &rhs) const noexcept { + return this->size() == rhs.size() && + std::equal(this->begin(), this->end(), rhs.begin()); + } + +-bool Str::operator!=(const Str &rhs) const noexcept { return !(*this == rhs); } ++CXX_CPP_EXPORT bool Str::operator!=(const Str &rhs) const noexcept { ++ return !(*this == rhs); ++} + +-bool Str::operator<(const Str &rhs) const noexcept { ++CXX_CPP_EXPORT bool Str::operator<(const Str &rhs) const noexcept { + return std::lexicographical_compare(this->begin(), this->end(), rhs.begin(), + rhs.end()); + } + +-bool Str::operator<=(const Str &rhs) const noexcept { ++CXX_CPP_EXPORT bool Str::operator<=(const Str &rhs) const noexcept { + // std::mismatch(this->begin(), this->end(), rhs.begin(), rhs.end()), except + // without Undefined Behavior on C++11 if rhs is shorter than *this. + const_iterator liter = this->begin(), lend = this->end(), riter = rhs.begin(), +@@ -311,27 +356,34 @@ bool Str::operator<=(const Str &rhs) const noexcept { + } + } + +-bool Str::operator>(const Str &rhs) const noexcept { return rhs < *this; } ++CXX_CPP_EXPORT bool Str::operator>(const Str &rhs) const noexcept { ++ return rhs < *this; ++} + +-bool Str::operator>=(const Str &rhs) const noexcept { return rhs <= *this; } ++CXX_CPP_EXPORT bool Str::operator>=(const Str &rhs) const noexcept { ++ return rhs <= *this; ++} + +-void Str::swap(Str &rhs) noexcept { ++CXX_CPP_EXPORT void Str::swap(Str &rhs) noexcept { + using std::swap; + swap(this->repr, rhs.repr); + } + +-std::ostream &operator<<(std::ostream &os, const Str &s) { ++CXX_CPP_EXPORT std::ostream &operator<<(std::ostream &os, const Str &s) { + os.write(s.data(), s.size()); + return os; + } + +-void sliceInit(void *self, const void *ptr, std::size_t len) noexcept { ++CXX_CPP_EXPORT void sliceInit(void *self, const void *ptr, ++ std::size_t len) noexcept { + cxxbridge1$slice$new(self, ptr, len); + } + +-void *slicePtr(const void *self) noexcept { return cxxbridge1$slice$ptr(self); } ++CXX_CPP_EXPORT void *slicePtr(const void *self) noexcept { ++ return cxxbridge1$slice$ptr(self); ++} + +-std::size_t sliceLen(const void *self) noexcept { ++CXX_CPP_EXPORT std::size_t sliceLen(const void *self) noexcept { + return cxxbridge1$slice$len(self); + } + +@@ -402,7 +454,8 @@ static const char *errorCopy(const char *ptr, std::size_t len) { + } + + extern "C" { +-const char *cxxbridge1$error(const char *ptr, std::size_t len) noexcept { ++CXX_RS_EXPORT const char *cxxbridge1$error(const char *ptr, ++ std::size_t len) noexcept { + return errorCopy(ptr, len); + } + } // extern "C" +@@ -479,23 +532,24 @@ void destroy(T *ptr) { + } // namespace + + extern "C" { +-void cxxbridge1$unique_ptr$std$string$null( ++CXX_RS_EXPORT void cxxbridge1$unique_ptr$std$string$null( + std::unique_ptr *ptr) noexcept { + new (ptr) std::unique_ptr(); + } +-void cxxbridge1$unique_ptr$std$string$raw(std::unique_ptr *ptr, +- std::string *raw) noexcept { ++CXX_RS_EXPORT void ++cxxbridge1$unique_ptr$std$string$raw(std::unique_ptr *ptr, ++ std::string *raw) noexcept { + new (ptr) std::unique_ptr(raw); + } +-const std::string *cxxbridge1$unique_ptr$std$string$get( ++CXX_RS_EXPORT const std::string *cxxbridge1$unique_ptr$std$string$get( + const std::unique_ptr &ptr) noexcept { + return ptr.get(); + } +-std::string *cxxbridge1$unique_ptr$std$string$release( ++CXX_RS_EXPORT std::string *cxxbridge1$unique_ptr$std$string$release( + std::unique_ptr &ptr) noexcept { + return ptr.release(); + } +-void cxxbridge1$unique_ptr$std$string$drop( ++CXX_RS_EXPORT void cxxbridge1$unique_ptr$std$string$drop( + std::unique_ptr *ptr) noexcept { + ptr->~unique_ptr(); + } +@@ -510,65 +564,65 @@ static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *), + } // namespace + + #define STD_VECTOR_OPS(RUST_TYPE, CXX_TYPE) \ +- std::size_t cxxbridge1$std$vector$##RUST_TYPE##$size( \ ++ CXX_RS_EXPORT std::size_t cxxbridge1$std$vector$##RUST_TYPE##$size( \ + const std::vector &s) noexcept { \ + return s.size(); \ + } \ +- CXX_TYPE *cxxbridge1$std$vector$##RUST_TYPE##$get_unchecked( \ ++ CXX_RS_EXPORT CXX_TYPE *cxxbridge1$std$vector$##RUST_TYPE##$get_unchecked( \ + std::vector *s, std::size_t pos) noexcept { \ + return &(*s)[pos]; \ + } \ +- void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$null( \ ++ CXX_RS_EXPORT void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$null( \ + std::unique_ptr> *ptr) noexcept { \ + new (ptr) std::unique_ptr>(); \ + } \ +- void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$raw( \ ++ CXX_RS_EXPORT void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$raw( \ + std::unique_ptr> *ptr, \ + std::vector *raw) noexcept { \ + new (ptr) std::unique_ptr>(raw); \ + } \ +- const std::vector \ ++ CXX_RS_EXPORT const std::vector \ + *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$get( \ + const std::unique_ptr> &ptr) noexcept { \ + return ptr.get(); \ + } \ +- std::vector \ ++ CXX_RS_EXPORT std::vector \ + *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$release( \ + std::unique_ptr> &ptr) noexcept { \ + return ptr.release(); \ + } \ +- void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$drop( \ ++ CXX_RS_EXPORT void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$drop( \ + std::unique_ptr> *ptr) noexcept { \ + ptr->~unique_ptr(); \ + } + + #define STD_VECTOR_TRIVIAL_OPS(RUST_TYPE, CXX_TYPE) \ +- void cxxbridge1$std$vector$##RUST_TYPE##$push_back( \ ++ CXX_RS_EXPORT void cxxbridge1$std$vector$##RUST_TYPE##$push_back( \ + std::vector *v, CXX_TYPE *value) noexcept { \ + v->push_back(std::move(*value)); \ + destroy(value); \ + } \ +- void cxxbridge1$std$vector$##RUST_TYPE##$pop_back(std::vector *v, \ +- CXX_TYPE *out) noexcept { \ ++ CXX_RS_EXPORT void cxxbridge1$std$vector$##RUST_TYPE##$pop_back( \ ++ std::vector *v, CXX_TYPE *out) noexcept { \ + new (out) CXX_TYPE(std::move(v->back())); \ + v->pop_back(); \ + } + + #define RUST_VEC_EXTERNS(RUST_TYPE, CXX_TYPE) \ +- void cxxbridge1$rust_vec$##RUST_TYPE##$new( \ ++ CXX_RS_EXPORT void cxxbridge1$rust_vec$##RUST_TYPE##$new( \ + rust::Vec *ptr) noexcept; \ +- void cxxbridge1$rust_vec$##RUST_TYPE##$drop( \ ++ CXX_RS_EXPORT void cxxbridge1$rust_vec$##RUST_TYPE##$drop( \ + rust::Vec *ptr) noexcept; \ +- std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$len( \ ++ CXX_RS_EXPORT std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$len( \ + const rust::Vec *ptr) noexcept; \ +- std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$capacity( \ ++ CXX_RS_EXPORT std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$capacity( \ + const rust::Vec *ptr) noexcept; \ +- const CXX_TYPE *cxxbridge1$rust_vec$##RUST_TYPE##$data( \ ++ CXX_RS_EXPORT const CXX_TYPE *cxxbridge1$rust_vec$##RUST_TYPE##$data( \ + const rust::Vec *ptr) noexcept; \ +- void cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total( \ ++ CXX_RS_EXPORT void cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total( \ + rust::Vec *ptr, std::size_t new_cap) noexcept; \ +- void cxxbridge1$rust_vec$##RUST_TYPE##$set_len(rust::Vec *ptr, \ +- std::size_t len) noexcept; ++ CXX_RS_EXPORT void cxxbridge1$rust_vec$##RUST_TYPE##$set_len( \ ++ rust::Vec *ptr, std::size_t len) noexcept; + + #define RUST_VEC_OPS(RUST_TYPE, CXX_TYPE) \ + template <> \ +@@ -603,52 +657,52 @@ static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *), + #define SHARED_PTR_OPS(RUST_TYPE, CXX_TYPE) \ + static_assert(sizeof(std::shared_ptr) == 2 * sizeof(void *), ""); \ + static_assert(alignof(std::shared_ptr) == alignof(void *), ""); \ +- void cxxbridge1$std$shared_ptr$##RUST_TYPE##$null( \ ++ CXX_RS_EXPORT void cxxbridge1$std$shared_ptr$##RUST_TYPE##$null( \ + std::shared_ptr *ptr) noexcept { \ + new (ptr) std::shared_ptr(); \ + } \ +- CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$uninit( \ ++ CXX_RS_EXPORT CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$uninit( \ + std::shared_ptr *ptr) noexcept { \ + CXX_TYPE *uninit = \ + reinterpret_cast(new rust::MaybeUninit); \ + new (ptr) std::shared_ptr(uninit); \ + return uninit; \ + } \ +- void cxxbridge1$std$shared_ptr$##RUST_TYPE##$clone( \ ++ CXX_RS_EXPORT void cxxbridge1$std$shared_ptr$##RUST_TYPE##$clone( \ + const std::shared_ptr &self, \ + std::shared_ptr *ptr) noexcept { \ + new (ptr) std::shared_ptr(self); \ + } \ +- const CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$get( \ ++ CXX_RS_EXPORT const CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$get( \ + const std::shared_ptr &self) noexcept { \ + return self.get(); \ + } \ +- void cxxbridge1$std$shared_ptr$##RUST_TYPE##$drop( \ ++ CXX_RS_EXPORT void cxxbridge1$std$shared_ptr$##RUST_TYPE##$drop( \ + const std::shared_ptr *self) noexcept { \ + self->~shared_ptr(); \ + } \ + static_assert(sizeof(std::weak_ptr) == 2 * sizeof(void *), ""); \ + static_assert(alignof(std::weak_ptr) == alignof(void *), ""); \ +- void cxxbridge1$std$weak_ptr$##RUST_TYPE##$null( \ ++ CXX_RS_EXPORT void cxxbridge1$std$weak_ptr$##RUST_TYPE##$null( \ + std::weak_ptr *ptr) noexcept { \ + new (ptr) std::weak_ptr(); \ + } \ +- void cxxbridge1$std$weak_ptr$##RUST_TYPE##$clone( \ ++ CXX_RS_EXPORT void cxxbridge1$std$weak_ptr$##RUST_TYPE##$clone( \ + const std::weak_ptr &self, \ + std::weak_ptr *ptr) noexcept { \ + new (ptr) std::weak_ptr(self); \ + } \ +- void cxxbridge1$std$weak_ptr$##RUST_TYPE##$downgrade( \ ++ CXX_RS_EXPORT void cxxbridge1$std$weak_ptr$##RUST_TYPE##$downgrade( \ + const std::shared_ptr &shared, \ + std::weak_ptr *weak) noexcept { \ + new (weak) std::weak_ptr(shared); \ + } \ +- void cxxbridge1$std$weak_ptr$##RUST_TYPE##$upgrade( \ ++ CXX_RS_EXPORT void cxxbridge1$std$weak_ptr$##RUST_TYPE##$upgrade( \ + const std::weak_ptr &weak, \ + std::shared_ptr *shared) noexcept { \ + new (shared) std::shared_ptr(weak.lock()); \ + } \ +- void cxxbridge1$std$weak_ptr$##RUST_TYPE##$drop( \ ++ CXX_RS_EXPORT void cxxbridge1$std$weak_ptr$##RUST_TYPE##$drop( \ + const std::weak_ptr *self) noexcept { \ + self->~weak_ptr(); \ + } +-- +2.35.1.723.g4982287a31-goog +