diff --git a/CMakeLists.txt b/CMakeLists.txt index 94ab492..537b99b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -241,8 +241,8 @@ if(XYZ_PROTOCOL_IS_NOT_SUBPROJECT) # a throwaway interface. XYZ_PROTOCOL_ENABLE_REFLECTION is the # source-level macro protocol.h checks to include protocol_reflection.hxx # instead of its placeholder primary templates; it is distinct from - # this XYZ_PROTOCOL_BUILD_REFLECTION_TUTORIAL CMake option, which only - # gates whether this target exists at all. + # this XYZ_PROTOCOL_USE_REFLECTION CMake option, which only gates + # whether this target exists at all. xyz_add_test( NAME protocol_reflection_smoke_test @@ -267,6 +267,31 @@ if(XYZ_PROTOCOL_IS_NOT_SUBPROJECT) PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) set_target_properties(protocol_reflection_smoke_test PROPERTIES INTERPROCEDURAL_OPTIMIZATION OFF) + + # protocol_test.cc itself, built against this backend instead of the + # Python/libclang-generated headers. D's operator tests are excluded + # (not supported yet). + xyz_add_test( + NAME + protocol_test_reflection + VERSION + 26 + LINK_LIBRARIES + protocol + FILES + protocol_test.cc + interface_A.h + interface_A_Subset.h + interface_B.h + interface_C.h + tracking_allocator.h) + target_compile_options(protocol_test_reflection PRIVATE -freflection) + target_compile_definitions(protocol_test_reflection + PRIVATE XYZ_PROTOCOL_ENABLE_REFLECTION) + target_include_directories(protocol_test_reflection + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + set_target_properties(protocol_test_reflection PROPERTIES + INTERPROCEDURAL_OPTIMIZATION OFF) endif() add_executable(protocol_benchmark protocol_benchmark.cc) diff --git a/gh-reupload.sh b/gh-reupload.sh new file mode 100755 index 0000000..0a31656 --- /dev/null +++ b/gh-reupload.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# Force-push the reflection/00..19 branch stack after a local rebase. +# Existing PRs update in place; --force-with-lease refuses to clobber +# anyone else's push in the meantime. + +set -eu -o pipefail + +BRANCHES=( + reflection/00-python-exact-match + reflection/01-rename-vtable-fns + reflection/02-default-allocator + reflection/03-cmake-option + reflection/04-naming + reflection/05-members + reflection/06-types + reflection/07-vtable-layout + reflection/08-thunk + reflection/09-conformance + reflection/10-forwarders + reflection/11-protocol-reflection-slice + reflection/12-interface-a + reflection/13-overload-merging + reflection/14-interface-b + reflection/15-allocator-awareness + reflection/16-narrowing-a-subset + reflection/17-protocol-view + reflection/18-fix-clang-format-splice-break + reflection/19-swap-protocol-test +) + +for b in "${BRANCHES[@]}"; do + git push --force-with-lease origin "$b" +done diff --git a/gh-update.sh b/gh-update.sh new file mode 100755 index 0000000..1fd2f6f --- /dev/null +++ b/gh-update.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# Update the already-created reflection/00..19 stacked PRs: set each PR's +# body to its commit's own description, and append the PR's position in the +# stack (x/N) to its title. + +set -eu -o pipefail + +BRANCHES=( + reflection/00-python-exact-match + reflection/01-rename-vtable-fns + reflection/02-default-allocator + reflection/03-cmake-option + reflection/04-naming + reflection/05-members + reflection/06-types + reflection/07-vtable-layout + reflection/08-thunk + reflection/09-conformance + reflection/10-forwarders + reflection/11-protocol-reflection-slice + reflection/12-interface-a + reflection/13-overload-merging + reflection/14-interface-b + reflection/15-allocator-awareness + reflection/16-narrowing-a-subset + reflection/17-protocol-view + reflection/18-fix-clang-format-splice-break + reflection/19-swap-protocol-test +) + +TITLES=( + "Require exact return-type matches in generated protocol concepts" + "Rename get_vtable/get_mutable_vtable to get_const_vtable/get_vtable" + "Add a default allocator argument to the protocol primary template" + "Add XYZ_PROTOCOL_USE_REFLECTION cmake option to gate the reflection backend" + "Add naming.hxx: injective vtable/forwarder entry-name escaping" + "Add members.hxx: enumerating an interface's dispatchable member functions" + "Add types.hxx: synthesizing member and vtable-entry function types" + "Add vtable_layout.hxx: view_vtable/const_view_vtable for a bare interface" + "Add thunk.hxx: erased_call_thunk calling a pre-merged candidate type" + "Add conformance.hxx: duck-typed candidate merging and the reflection concepts" + "Add forwarders.hxx: per-member forwarder-base template and its combinator" + "Wire protocol_reflection.hxx: allocator-free single-method dispatch on Greeter" + "Extend the slice to mixed const/non-const, multi-method dispatch (A)" + "Add overload merging: duck-typed dispatch for overloaded members (C)" + "Add interface B alongside C, and fix vtable_entry_name over-escaping" + "Add allocator-awareness" + "Add narrowing conversions: A to A_Subset, concurrency stress test" + "Add protocol_view and protocol_view" + "Fix a clang-format-induced parse break in three erased_call_thunk uses" + "Swap protocol_test.cc to the reflection backend; enable protocol_test_reflection" +) + +N=${#BRANCHES[@]} + +for i in "${!BRANCHES[@]}"; do + branch="${BRANCHES[$i]}" + position=$((i + 1)) + body_file=$(mktemp) + git log -1 --format=%b "$branch" > "$body_file" + gh pr edit "$branch" \ + --title "${TITLES[$i]} (${position}/${N})" \ + --body-file "$body_file" + rm -f "$body_file" +done diff --git a/gh.sh b/gh.sh new file mode 100755 index 0000000..984afb6 --- /dev/null +++ b/gh.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# Push the reflection/00..19 branch stack and open one draft stacked PR per +# branch, each targeting the previous branch in the stack. + +set -eu -o pipefail + +BRANCHES=( + reflection/00-python-exact-match + reflection/01-rename-vtable-fns + reflection/02-default-allocator + reflection/03-cmake-option + reflection/04-naming + reflection/05-members + reflection/06-types + reflection/07-vtable-layout + reflection/08-thunk + reflection/09-conformance + reflection/10-forwarders + reflection/11-protocol-reflection-slice + reflection/12-interface-a + reflection/13-overload-merging + reflection/14-interface-b + reflection/15-allocator-awareness + reflection/16-narrowing-a-subset + reflection/17-protocol-view + reflection/18-fix-clang-format-splice-break + reflection/19-swap-protocol-test +) + +BASES=( + tutorials + reflection/00-python-exact-match + reflection/01-rename-vtable-fns + reflection/02-default-allocator + reflection/03-cmake-option + reflection/04-naming + reflection/05-members + reflection/06-types + reflection/07-vtable-layout + reflection/08-thunk + reflection/09-conformance + reflection/10-forwarders + reflection/11-protocol-reflection-slice + reflection/12-interface-a + reflection/13-overload-merging + reflection/14-interface-b + reflection/15-allocator-awareness + reflection/16-narrowing-a-subset + reflection/17-protocol-view + reflection/18-fix-clang-format-splice-break +) + +TITLES=( + "Require exact return-type matches in generated protocol concepts" + "Rename get_vtable/get_mutable_vtable to get_const_vtable/get_vtable" + "Add a default allocator argument to the protocol primary template" + "Add XYZ_PROTOCOL_USE_REFLECTION cmake option to gate the reflection backend" + "Add naming.hxx: injective vtable/forwarder entry-name escaping" + "Add members.hxx: enumerating an interface's dispatchable member functions" + "Add types.hxx: synthesizing member and vtable-entry function types" + "Add vtable_layout.hxx: view_vtable/const_view_vtable for a bare interface" + "Add thunk.hxx: erased_call_thunk calling a pre-merged candidate type" + "Add conformance.hxx: duck-typed candidate merging and the reflection concepts" + "Add forwarders.hxx: per-member forwarder-base template and its combinator" + "Wire protocol_reflection.hxx: allocator-free single-method dispatch on Greeter" + "Extend the slice to mixed const/non-const, multi-method dispatch (A)" + "Add overload merging: duck-typed dispatch for overloaded members (C)" + "Add interface B alongside C, and fix vtable_entry_name over-escaping" + "Add allocator-awareness" + "Add narrowing conversions: A to A_Subset, concurrency stress test" + "Add protocol_view and protocol_view" + "Fix a clang-format-induced parse break in three erased_call_thunk uses" + "Swap protocol_test.cc to the reflection backend; enable protocol_test_reflection" +) + +git push -u origin "${BRANCHES[@]}" + +for i in "${!BRANCHES[@]}"; do + gh pr create \ + --draft \ + --base "${BASES[$i]}" \ + --head "${BRANCHES[$i]}" \ + --title "${TITLES[$i]}" \ + --body "" +done diff --git a/protocol_test.cc b/protocol_test.cc index 664de2a..0c2c639 100644 --- a/protocol_test.cc +++ b/protocol_test.cc @@ -29,11 +29,19 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#ifdef XYZ_PROTOCOL_ENABLE_REFLECTION +// interface_D.h isn't needed: D's operator tests are excluded below. +#include "interface_A.h" +#include "interface_A_Subset.h" +#include "interface_B.h" +#include "interface_C.h" +#else #include "generated/protocol_A.h" #include "generated/protocol_A_Subset.h" #include "generated/protocol_B.h" #include "generated/protocol_C.h" #include "generated/protocol_D.h" +#endif // XYZ_PROTOCOL_ENABLE_REFLECTION #include "tracking_allocator.h" namespace { @@ -701,6 +709,11 @@ TEST(ProtocolViewTest, PreventConstructionFromRValues) { "compatible protocol"); } +// D's operators aren't supported by the reflection backend yet: naming.hxx +// has no scheme for operators (they have no identifier_of), so reflecting +// over D's members is a compile error, not just a failing dispatch call. +#ifndef XYZ_PROTOCOL_ENABLE_REFLECTION + class DLike { int value_ = 0; @@ -917,6 +930,8 @@ TEST(ProtocolViewTest, ProtocolViewDOperators) { EXPECT_EQ(d[5], 10); } +#endif // XYZ_PROTOCOL_ENABLE_REFLECTION + TEST(ProtocolViewTest, NarrowingConversion) { ALike a_obj; xyz::protocol_view view_a(a_obj);