From 821b204bc40f1fbd6629a3d71acda2963d476df1 Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Wed, 16 Mar 2022 12:23:57 -0700 Subject: [PATCH 1/3] Add CXX_RS_EXPORT, CXX_CPP_EXPORT macros to cxx.cc. In some non-Cargo build configurations, the Rust and C++ side of cxx bindings may end up in different binaries. In some environments, this requires symbols to be explicitly exported using __declspec(dllexport) or similar directives. A previous change added the --cxx-impl-annotations switch on the cxx-gen command line tool, providing the opportunity to specify such directives for dynamically generated parts of the cxx bindings. It turns out to be similarly useful to export symbols from cxx.cc. This change adds a pair of preprocessor symbols which folks can define if they wish to export these symbols too. --- gen/cmd/src/app.rs | 10 +- src/cxx.cc | 267 +++++++++++++++++++++++---------------------- 2 files changed, 146 insertions(+), 131 deletions(-) diff --git a/gen/cmd/src/app.rs b/gen/cmd/src/app.rs index 97288c105..824864c74 100644 --- a/gen/cmd/src/app.rs +++ b/gen/cmd/src/app.rs @@ -133,7 +133,15 @@ Optional annotation for implementations of C++ function wrappers that may be exposed to Rust. You may for example need to provide __declspec(dllexport) or __attribute__((visibility(\"default\"))) if Rust code from one shared object or executable depends on -these C++ functions in another."; +these C++ functions in another. + +If you need to use this option, you might also consider similarly +defining either or both of the preprocessor symbols CXX_RS_EXPORT +and CXX_CPP_EXPORT when compiling cxx.cc. CXX_RS_EXPORT +attaches to symbols exported from cxx.cc which are typically used +by Rust code; CXX_CPP_EXPORT attaches to symbols which are used +by C++ code. +"; Arg::new(CXX_IMPL_ANNOTATIONS) .long(CXX_IMPL_ANNOTATIONS) .takes_value(true) diff --git a/src/cxx.cc b/src/cxx.cc index 1601a05ab..7b1601249 100644 --- a/src/cxx.cc +++ b/src/cxx.cc @@ -3,71 +3,78 @@ #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, +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, +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, +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, +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; -bool cxxbridge1$string$from_utf8(rust::String *self, const char *ptr, +CXX_RS_EXPORT bool cxxbridge1$string$from_utf8(rust::String *self, const char *ptr, std::size_t len) noexcept; -void cxxbridge1$string$from_utf8_lossy(rust::String *self, const char *ptr, +CXX_RS_EXPORT void cxxbridge1$string$from_utf8_lossy(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 bool cxxbridge1$string$from_utf16(rust::String *self, const char16_t *ptr, std::size_t len) noexcept; -void cxxbridge1$string$from_utf16_lossy(rust::String *self, const char16_t *ptr, +CXX_RS_EXPORT void cxxbridge1$string$from_utf16_lossy(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, +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; -void cxxbridge1$string$reserve_total(rust::String *self, +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, +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; -const char *cxxbridge1$str$ptr(const rust::Str *self) noexcept; -std::size_t cxxbridge1$str$len(const rust::Str *self) 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, +CXX_RS_EXPORT 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$ptr(const void *self) noexcept; +CXX_RS_EXPORT std::size_t cxxbridge1$slice$len(const void *self) noexcept; } // extern "C" namespace rust { @@ -91,17 +98,17 @@ static bool is_aligned(const void *ptr) noexcept { return !(iptr % alignof(T)); } -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)) { @@ -115,27 +122,27 @@ 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); assert(is_aligned(s)); 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); assert(is_aligned(s)); initString(this, @@ -146,46 +153,46 @@ String::String(const char16_t *s, std::size_t len) { struct String::lossy_t {}; -String::String(lossy_t, const char *s, std::size_t len) noexcept { +CXX_CPP_EXPORT String::String(lossy_t, const char *s, std::size_t len) noexcept { cxxbridge1$string$from_utf8_lossy( this, s == nullptr && len == 0 ? reinterpret_cast(1) : s, len); } -String::String(lossy_t, const char16_t *s, std::size_t len) noexcept { +CXX_CPP_EXPORT String::String(lossy_t, const char16_t *s, std::size_t len) noexcept { cxxbridge1$string$from_utf16_lossy( this, s == nullptr && len == 0 ? reinterpret_cast(2) : s, len); } -String String::lossy(const std::string &s) noexcept { +CXX_CPP_EXPORT String String::lossy(const std::string &s) noexcept { return String::lossy(s.data(), s.length()); } -String String::lossy(const char *s) noexcept { +CXX_CPP_EXPORT String String::lossy(const char *s) noexcept { assert(s != nullptr); return String::lossy(s, std::strlen(s)); } -String String::lossy(const char *s, std::size_t len) noexcept { +CXX_CPP_EXPORT String String::lossy(const char *s, std::size_t len) noexcept { assert(s != nullptr || len == 0); return String(lossy_t{}, s, len); } -String String::lossy(const char16_t *s) noexcept { +CXX_CPP_EXPORT String String::lossy(const char16_t *s) noexcept { assert(s != nullptr); assert(is_aligned(s)); return String(lossy_t{}, s, std::char_traits::length(s)); } -String String::lossy(const char16_t *s, std::size_t len) noexcept { +CXX_CPP_EXPORT String String::lossy(const char16_t *s, std::size_t len) noexcept { assert(s != nullptr || len == 0); assert(is_aligned(s)); return String(lossy_t{}, s, 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); @@ -193,32 +200,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(); @@ -226,128 +233,128 @@ 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(), @@ -364,27 +371,27 @@ 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); } @@ -455,7 +462,7 @@ 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" @@ -532,23 +539,23 @@ 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, +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(); } @@ -563,67 +570,67 @@ 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; \ - void cxxbridge1$rust_vec$##RUST_TYPE##$truncate(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; \ + CXX_RS_EXPORT void cxxbridge1$rust_vec$##RUST_TYPE##$truncate( \ + rust::Vec *ptr, std::size_t len) noexcept; #define RUST_VEC_OPS(RUST_TYPE, CXX_TYPE) \ template <> \ @@ -662,52 +669,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(); \ } From 38d91cf4993fcd43ac1e32f54065cb48d6db9e28 Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Wed, 16 Mar 2022 12:24:49 -0700 Subject: [PATCH 2/3] clang-format No functional changes. --- src/cxx.cc | 154 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 103 insertions(+), 51 deletions(-) diff --git a/src/cxx.cc b/src/cxx.cc index 7b1601249..518513f15 100644 --- a/src/cxx.cc +++ b/src/cxx.cc @@ -11,8 +11,9 @@ #endif extern "C" { -CXX_RS_EXPORT 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); } @@ -21,58 +22,72 @@ CXX_RS_EXPORT void cxxbridge1$cxx_string$destroy(std::string *s) noexcept { s->~string(); } -CXX_RS_EXPORT 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(); } -CXX_RS_EXPORT 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(); } -CXX_RS_EXPORT 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(); +} -CXX_RS_EXPORT 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); } -CXX_RS_EXPORT 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 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 void cxxbridge1$string$from_utf8_lossy(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$from_utf16_lossy(rust::String *self, const char16_t *ptr, - std::size_t len) noexcept; + 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 void cxxbridge1$string$from_utf8_lossy(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$from_utf16_lossy(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 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; + size_t new_cap) noexcept; // rust::Str 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 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; + 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 CXX_RS_EXPORT void cxxbridge1$slice$new(void *self, const void *ptr, - std::size_t len) noexcept; + 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" @@ -90,7 +105,7 @@ void panic [[noreturn]] (const char *msg) { #endif } -template void panic [[noreturn]] (const char *msg); +template void panic[[noreturn]] (const char *msg); template static bool is_aligned(const void *ptr) noexcept { @@ -122,7 +137,9 @@ static void initString(String *self, const char16_t *s, std::size_t len) { } } -CXX_CPP_EXPORT 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()); +} CXX_CPP_EXPORT String::String(const char *s) { assert(s != nullptr); @@ -153,13 +170,15 @@ CXX_CPP_EXPORT String::String(const char16_t *s, std::size_t len) { struct String::lossy_t {}; -CXX_CPP_EXPORT String::String(lossy_t, const char *s, std::size_t len) noexcept { +CXX_CPP_EXPORT String::String(lossy_t, const char *s, + std::size_t len) noexcept { cxxbridge1$string$from_utf8_lossy( this, s == nullptr && len == 0 ? reinterpret_cast(1) : s, len); } -CXX_CPP_EXPORT String::String(lossy_t, const char16_t *s, std::size_t len) noexcept { +CXX_CPP_EXPORT String::String(lossy_t, const char16_t *s, + std::size_t len) noexcept { cxxbridge1$string$from_utf16_lossy( this, s == nullptr && len == 0 ? reinterpret_cast(2) : s, @@ -186,7 +205,8 @@ CXX_CPP_EXPORT String String::lossy(const char16_t *s) noexcept { return String(lossy_t{}, s, std::char_traits::length(s)); } -CXX_CPP_EXPORT String String::lossy(const char16_t *s, std::size_t len) noexcept { +CXX_CPP_EXPORT String String::lossy(const char16_t *s, + std::size_t len) noexcept { assert(s != nullptr || len == 0); assert(is_aligned(s)); return String(lossy_t{}, s, len); @@ -249,11 +269,17 @@ CXX_CPP_EXPORT String::iterator String::end() noexcept { return const_cast(this->data()) + this->size(); } -CXX_CPP_EXPORT String::const_iterator String::begin() const noexcept { return this->cbegin(); } +CXX_CPP_EXPORT String::const_iterator String::begin() const noexcept { + return this->cbegin(); +} -CXX_CPP_EXPORT String::const_iterator String::end() const noexcept { return this->cend(); } +CXX_CPP_EXPORT String::const_iterator String::end() const noexcept { + return this->cend(); +} -CXX_CPP_EXPORT String::const_iterator String::cbegin() const noexcept { return this->data(); } +CXX_CPP_EXPORT String::const_iterator String::cbegin() const noexcept { + return this->data(); +} CXX_CPP_EXPORT String::const_iterator String::cend() const noexcept { return this->data() + this->size(); @@ -298,15 +324,20 @@ CXX_CPP_EXPORT std::ostream &operator<<(std::ostream &os, const String &s) { CXX_CPP_EXPORT Str::Str() noexcept { cxxbridge1$str$new(this); } -CXX_CPP_EXPORT 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); +} -CXX_CPP_EXPORT 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"); } } -CXX_CPP_EXPORT 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()); +} CXX_CPP_EXPORT Str::Str(const char *s) { assert(s != nullptr); @@ -324,19 +355,29 @@ CXX_CPP_EXPORT Str::operator std::string() const { return std::string(this->data(), this->size()); } -CXX_CPP_EXPORT 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); +} -CXX_CPP_EXPORT 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); +} CXX_CPP_EXPORT std::size_t Str::length() const noexcept { return this->size(); } CXX_CPP_EXPORT bool Str::empty() const noexcept { return this->size() == 0; } -CXX_CPP_EXPORT Str::const_iterator Str::begin() const noexcept { return this->cbegin(); } +CXX_CPP_EXPORT Str::const_iterator Str::begin() const noexcept { + return this->cbegin(); +} -CXX_CPP_EXPORT Str::const_iterator Str::end() const noexcept { return this->cend(); } +CXX_CPP_EXPORT Str::const_iterator Str::end() const noexcept { + return this->cend(); +} -CXX_CPP_EXPORT Str::const_iterator Str::cbegin() const noexcept { return this->data(); } +CXX_CPP_EXPORT Str::const_iterator Str::cbegin() const noexcept { + return this->data(); +} CXX_CPP_EXPORT Str::const_iterator Str::cend() const noexcept { return this->data() + this->size(); @@ -347,7 +388,9 @@ CXX_CPP_EXPORT bool Str::operator==(const Str &rhs) const noexcept { std::equal(this->begin(), this->end(), rhs.begin()); } -CXX_CPP_EXPORT 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); +} CXX_CPP_EXPORT bool Str::operator<(const Str &rhs) const noexcept { return std::lexicographical_compare(this->begin(), this->end(), rhs.begin(), @@ -371,9 +414,13 @@ CXX_CPP_EXPORT bool Str::operator<=(const Str &rhs) const noexcept { } } -CXX_CPP_EXPORT 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; +} -CXX_CPP_EXPORT 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; +} CXX_CPP_EXPORT void Str::swap(Str &rhs) noexcept { using std::swap; @@ -385,11 +432,14 @@ CXX_CPP_EXPORT std::ostream &operator<<(std::ostream &os, const Str &s) { return os; } -CXX_CPP_EXPORT 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); } -CXX_CPP_EXPORT 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); +} CXX_CPP_EXPORT std::size_t sliceLen(const void *self) noexcept { return cxxbridge1$slice$len(self); @@ -462,7 +512,8 @@ static const char *errorCopy(const char *ptr, std::size_t len) { } extern "C" { -CXX_RS_EXPORT 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" @@ -543,8 +594,9 @@ CXX_RS_EXPORT void cxxbridge1$unique_ptr$std$string$null( std::unique_ptr *ptr) noexcept { new (ptr) std::unique_ptr(); } -CXX_RS_EXPORT 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); } CXX_RS_EXPORT const std::string *cxxbridge1$unique_ptr$std$string$get( From 08be363fe758a3213ed021a0e1296cf10dd83833 Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Wed, 16 Mar 2022 14:55:51 -0700 Subject: [PATCH 3/3] Update cmd test. --- gen/cmd/src/test.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gen/cmd/src/test.rs b/gen/cmd/src/test.rs index 33a61fdf6..3fe4fd370 100644 --- a/gen/cmd/src/test.rs +++ b/gen/cmd/src/test.rs @@ -23,6 +23,13 @@ OPTIONS: __declspec(dllexport) or __attribute__((visibility(\"default\"))) if Rust code from one shared object or executable depends on these C++ functions in another. + + If you need to use this option, you might also consider similarly + defining either or both of the preprocessor symbols CXX_RS_EXPORT + and CXX_CPP_EXPORT when compiling cxx.cc. CXX_RS_EXPORT + attaches to symbols exported from cxx.cc which are typically used + by Rust code; CXX_CPP_EXPORT attaches to symbols which are used + by C++ code. -h, --help Print help information.