Skip to content

Commit

Permalink
Library Forwarding: Fix build for clang < 16
Browse files Browse the repository at this point in the history
  • Loading branch information
neobrain committed Jan 31, 2024
1 parent b40d8f5 commit a4c1aaa
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
17 changes: 13 additions & 4 deletions ThunkLibs/include/common/Host.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,13 @@ const host_layout<T>& to_host_layout(const T& t) {
return reinterpret_cast<const host_layout<T>&>(t);
}

template<typename T>
constexpr bool is_long_or_longlong =
std::is_same_v<T, long> ||
std::is_same_v<T, unsigned long> ||
std::is_same_v<T, long long> ||
std::is_same_v<T, unsigned long long>;

template<typename T>
struct host_layout<T*> {
T* data;
Expand All @@ -243,10 +250,12 @@ struct host_layout<T*> {
// This is useful for handling "long"/"long long" on 64-bit, which are distinct types
// but have equal data layout.
template<typename U>
explicit host_layout(const guest_layout<U*>& from) requires (std::is_integral_v<T> && std::is_integral_v<U> && sizeof(T) == sizeof(U) && std::is_same_v<std::make_signed_t<std::remove_cv_t<T>>, long> && std::is_convertible_v<T, U> && std::is_signed_v<T> == std::is_signed_v<U>) : data { (T*)(uintptr_t)from.data } {
}
template<typename U>
explicit host_layout(const guest_layout<U*>& from) requires (std::is_integral_v<T> && std::is_integral_v<U> && sizeof(T) == sizeof(U) && std::is_same_v<std::make_signed_t<std::remove_cv_t<T>>, long long> && std::is_convertible_v<T, U> && std::is_signed_v<T> == std::is_signed_v<U>) : data { (T*)(uintptr_t)from.data } {
explicit host_layout(const guest_layout<U*>& from) requires (is_long_or_longlong<std::remove_cv_t<T>> && std::is_integral_v<U> && std::is_convertible_v<T, U> && std::is_signed_v<T> == std::is_signed_v<U>
#if __clang_major__ >= 16
// Old clang versions don't support using sizeof on incomplete types when evaluating requires()
&& sizeof(T) == sizeof(U)
#endif
) : data { (T*)(uintptr_t)from.data } {
}

// Allow conversion of pointers to 8-bit integer types to "char*".
Expand Down
6 changes: 4 additions & 2 deletions unittests/ThunkLibs/generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,12 +305,14 @@ SourceWithAST Fixture::run_thunkgen_host(std::string_view prelude, std::string_v
" template<typename U> explicit host_layout(const guest_layout<U>&) requires (std::is_integral_v<U> && sizeof(U) <= sizeof(T) && std::is_convertible_v<T, U> && std::is_signed_v<T> == std::is_signed_v<U>);\n"
"};\n"
"\n"
"template<typename T> constexpr bool is_long = std::is_same_v<T, long> || std::is_same_v<T, unsigned long>;\n"
"template<typename T> constexpr bool is_longlong = std::is_same_v<T, long long> || std::is_same_v<T, unsigned long long>;\n"
"template<typename T>\n"
"struct host_layout<T*> {\n"
" T* data;\n"
" explicit host_layout(const guest_layout<T*>&);\n"
" template<typename U> explicit host_layout(const guest_layout<U*>&) requires (std::is_integral_v<T> && std::is_integral_v<U> && sizeof(T) == sizeof(U) && std::is_same_v<std::make_signed_t<std::remove_cv_t<T>>, long> && std::is_convertible_v<T, U> && std::is_signed_v<T> == std::is_signed_v<U>);\n"
" template<typename U> explicit host_layout(const guest_layout<U*>&) requires (std::is_integral_v<T> && std::is_integral_v<U> && sizeof(T) == sizeof(U) && std::is_same_v<std::make_signed_t<std::remove_cv_t<T>>, long long> && std::is_convertible_v<T, U> && std::is_signed_v<T> == std::is_signed_v<U>);\n"
" template<typename U> explicit host_layout(const guest_layout<U*>&) requires (std::is_integral_v<U> && sizeof(U) == sizeof(long) && sizeof(long) == 8 && is_long<std::remove_cv_t<T>> && std::is_convertible_v<T, U> && std::is_signed_v<T> == std::is_signed_v<U>);\n"
" template<typename U> explicit host_layout(const guest_layout<U*>&) requires (std::is_integral_v<U> && sizeof(U) == sizeof(long long) && is_longlong<std::remove_cv_t<T>> && std::is_convertible_v<T, U> && std::is_signed_v<T> == std::is_signed_v<U>);\n"
" template<typename U> explicit host_layout(const guest_layout<U*>&) requires (std::is_same_v<std::remove_cv_t<T>, char> && std::is_integral_v<U> && std::is_convertible_v<T, U> && sizeof(U) == 1);\n"
" template<typename U> explicit host_layout(const guest_layout<U*>&) requires (std::is_same_v<std::remove_cv_t<T>, wchar_t> && std::is_integral_v<U> && std::is_convertible_v<T, U> && sizeof(U) == sizeof(wchar_t));\n"
"};\n"
Expand Down

0 comments on commit a4c1aaa

Please sign in to comment.