From 80bd58758f042ae90a96dcb312abbd3efb49dddf Mon Sep 17 00:00:00 2001 From: Enrico Seiler Date: Fri, 26 Jul 2024 16:18:31 +0200 Subject: [PATCH] Fix C++23: ~heap_object() with incomplete types --- schema_salad/cpp_codegen.py | 16 +++++++++++++++- schema_salad/tests/cpp_tests/01_single_record.h | 5 ++++- schema_salad/tests/cpp_tests/02_two_records.h | 5 ++++- .../tests/cpp_tests/03_simple_inheritance.h | 5 ++++- .../tests/cpp_tests/04_abstract_inheritance.h | 5 ++++- schema_salad/tests/cpp_tests/05_specialization.h | 5 ++++- 6 files changed, 35 insertions(+), 6 deletions(-) diff --git a/schema_salad/cpp_codegen.py b/schema_salad/cpp_codegen.py index 8c2066ed..1326c40d 100644 --- a/schema_salad/cpp_codegen.py +++ b/schema_salad/cpp_codegen.py @@ -875,7 +875,7 @@ class heap_object { *data = std::forward(oth); } - ~heap_object() = default; + ~heap_object(); auto operator=(heap_object const& oth) -> heap_object& { *data = *oth; @@ -953,6 +953,20 @@ class heap_object { for key in self.unionDefinitions: self.unionDefinitions[key].writeDefinition(self.target, " ") + # CPP23: std::unique_ptr in heap_object is constexpr. + # Hence, the compiler will try to instantiate the destructor on definition. + # If the destructor was defined inside heap_object, other classes would only + # be forward declared at this point. + # This results in an error, because the destructor cannot be generated for + # incomplete types. + # Therefore, the destructor is defined here, after all classes have been defined. + self.target.write( + """template +heap_object::~heap_object() = default; + +""" + ) + # write implementations for key in self.classDefinitions: self.classDefinitions[key].writeImplDefinition(self.target, "", " ") diff --git a/schema_salad/tests/cpp_tests/01_single_record.h b/schema_salad/tests/cpp_tests/01_single_record.h index c2d1ac4b..4933e3ae 100644 --- a/schema_salad/tests/cpp_tests/01_single_record.h +++ b/schema_salad/tests/cpp_tests/01_single_record.h @@ -200,7 +200,7 @@ class heap_object { *data = std::forward(oth); } - ~heap_object() = default; + ~heap_object(); auto operator=(heap_object const& oth) -> heap_object& { *data = *oth; @@ -246,6 +246,9 @@ struct MyRecord { }; } +template +heap_object::~heap_object() = default; + inline auto https___example_com_::MyRecord::toYaml() const -> YAML::Node { using ::toYaml; auto n = YAML::Node{}; diff --git a/schema_salad/tests/cpp_tests/02_two_records.h b/schema_salad/tests/cpp_tests/02_two_records.h index d014b3b1..8d4b2e72 100644 --- a/schema_salad/tests/cpp_tests/02_two_records.h +++ b/schema_salad/tests/cpp_tests/02_two_records.h @@ -200,7 +200,7 @@ class heap_object { *data = std::forward(oth); } - ~heap_object() = default; + ~heap_object(); auto operator=(heap_object const& oth) -> heap_object& { *data = *oth; @@ -256,6 +256,9 @@ struct MyRecordTwo { }; } +template +heap_object::~heap_object() = default; + inline auto https___example_com_::MyRecordOne::toYaml() const -> YAML::Node { using ::toYaml; auto n = YAML::Node{}; diff --git a/schema_salad/tests/cpp_tests/03_simple_inheritance.h b/schema_salad/tests/cpp_tests/03_simple_inheritance.h index d17f82e3..fe80d0b3 100644 --- a/schema_salad/tests/cpp_tests/03_simple_inheritance.h +++ b/schema_salad/tests/cpp_tests/03_simple_inheritance.h @@ -200,7 +200,7 @@ class heap_object { *data = std::forward(oth); } - ~heap_object() = default; + ~heap_object(); auto operator=(heap_object const& oth) -> heap_object& { *data = *oth; @@ -257,6 +257,9 @@ struct MyRecordTwo }; } +template +heap_object::~heap_object() = default; + inline auto https___example_com_::MyRecordOne::toYaml() const -> YAML::Node { using ::toYaml; auto n = YAML::Node{}; diff --git a/schema_salad/tests/cpp_tests/04_abstract_inheritance.h b/schema_salad/tests/cpp_tests/04_abstract_inheritance.h index 03689d1a..4530fd40 100644 --- a/schema_salad/tests/cpp_tests/04_abstract_inheritance.h +++ b/schema_salad/tests/cpp_tests/04_abstract_inheritance.h @@ -200,7 +200,7 @@ class heap_object { *data = std::forward(oth); } - ~heap_object() = default; + ~heap_object(); auto operator=(heap_object const& oth) -> heap_object& { *data = *oth; @@ -257,6 +257,9 @@ struct MyRecordTwo }; } +template +heap_object::~heap_object() = default; + inline https___example_com_::MyRecordOne::~MyRecordOne() = default; inline auto https___example_com_::MyRecordOne::toYaml() const -> YAML::Node { using ::toYaml; diff --git a/schema_salad/tests/cpp_tests/05_specialization.h b/schema_salad/tests/cpp_tests/05_specialization.h index 5db2c0c1..e20a4fd4 100644 --- a/schema_salad/tests/cpp_tests/05_specialization.h +++ b/schema_salad/tests/cpp_tests/05_specialization.h @@ -200,7 +200,7 @@ class heap_object { *data = std::forward(oth); } - ~heap_object() = default; + ~heap_object(); auto operator=(heap_object const& oth) -> heap_object& { *data = *oth; @@ -275,6 +275,9 @@ struct MyRecordTwo { }; } +template +heap_object::~heap_object() = default; + inline auto https___example_com_::FieldRecordA::toYaml() const -> YAML::Node { using ::toYaml; auto n = YAML::Node{};