diff options
| -rw-r--r-- | meta-oe/recipes-connectivity/thrift/thrift/0001-thrift-pr2755.patch | 599 | ||||
| -rw-r--r-- | meta-oe/recipes-connectivity/thrift/thrift_0.20.0.bb | 4 |
2 files changed, 602 insertions, 1 deletions
diff --git a/meta-oe/recipes-connectivity/thrift/thrift/0001-thrift-pr2755.patch b/meta-oe/recipes-connectivity/thrift/thrift/0001-thrift-pr2755.patch new file mode 100644 index 0000000000..b685d42728 --- /dev/null +++ b/meta-oe/recipes-connectivity/thrift/thrift/0001-thrift-pr2755.patch | |||
| @@ -0,0 +1,599 @@ | |||
| 1 | From f02ac2fb573bed72e9a2d1875807c6ff7ac19ec8 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Lukas Barth <mail@tinloaf.de> | ||
| 3 | Date: Wed, 8 Feb 2023 09:33:03 +0100 | ||
| 4 | Subject: [PATCH 1/5] Move default constructor and operator== implementation to | ||
| 5 | CPP file | ||
| 6 | |||
| 7 | Both the default constructor and operator== implementations reference | ||
| 8 | certain member functions of the class' members. As an example, the default | ||
| 9 | constructor references (i.e., "uses") the default constructors of its | ||
| 10 | members. | ||
| 11 | |||
| 12 | If a class contains a std::vector<Foo>, and Foo has only been *forward*- | ||
| 13 | declared (which happens often in Thrift-generated code), this creates | ||
| 14 | undefined behavior: The std::vector specification states that as long as | ||
| 15 | Foo is an incomplete type, it is fine to reference std::vector<Foo>, but | ||
| 16 | not any members (such as its default constructor). | ||
| 17 | |||
| 18 | Thus, we must defer our default constructor's implementation (which references | ||
| 19 | the default constructor of std::vector<Foo>) to a point where Foo is a | ||
| 20 | complete type. That is the case in the .cpp file. | ||
| 21 | |||
| 22 | The same holds for operator==. | ||
| 23 | |||
| 24 | Upstream-Status: Backport [https://github.com/apache/thrift/pull/2755] | ||
| 25 | |||
| 26 | Signed-off-by: Stanislav Angelovic <stanislav.angelovic.ext@siemens.com> | ||
| 27 | Signed-off-by: Peter Marko <peter.marko@siemens.com> | ||
| 28 | --- | ||
| 29 | .../src/thrift/generate/t_cpp_generator.cc | 187 +++++++++++------- | ||
| 30 | 1 file changed, 121 insertions(+), 66 deletions(-) | ||
| 31 | |||
| 32 | diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc | ||
| 33 | index 9724fae80..fecfa4bb5 100644 | ||
| 34 | --- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc | ||
| 35 | +++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc | ||
| 36 | @@ -146,11 +146,13 @@ public: | ||
| 37 | bool is_user_struct = false); | ||
| 38 | void generate_copy_constructor(std::ostream& out, t_struct* tstruct, bool is_exception); | ||
| 39 | void generate_move_constructor(std::ostream& out, t_struct* tstruct, bool is_exception); | ||
| 40 | + void generate_default_constructor(std::ostream& out, t_struct* tstruct, bool is_exception); | ||
| 41 | void generate_constructor_helper(std::ostream& out, | ||
| 42 | t_struct* tstruct, | ||
| 43 | bool is_excpetion, | ||
| 44 | bool is_move); | ||
| 45 | void generate_assignment_operator(std::ostream& out, t_struct* tstruct); | ||
| 46 | + void generate_equality_operator(std::ostream& out, t_struct* tstruct); | ||
| 47 | void generate_move_assignment_operator(std::ostream& out, t_struct* tstruct); | ||
| 48 | void generate_assignment_helper(std::ostream& out, t_struct* tstruct, bool is_move); | ||
| 49 | void generate_struct_reader(std::ostream& out, t_struct* tstruct, bool pointers = false); | ||
| 50 | @@ -914,6 +916,10 @@ void t_cpp_generator::generate_cpp_struct(t_struct* tstruct, bool is_exception) | ||
| 51 | generate_struct_reader(out, tstruct); | ||
| 52 | generate_struct_writer(out, tstruct); | ||
| 53 | generate_struct_swap(f_types_impl_, tstruct); | ||
| 54 | + if (!gen_no_default_operators_) { | ||
| 55 | + generate_equality_operator(f_types_impl_, tstruct); | ||
| 56 | + } | ||
| 57 | + generate_default_constructor(f_types_impl_, tstruct, is_exception); | ||
| 58 | generate_copy_constructor(f_types_impl_, tstruct, is_exception); | ||
| 59 | if (gen_moveable_) { | ||
| 60 | generate_move_constructor(f_types_impl_, tstruct, is_exception); | ||
| 61 | @@ -934,6 +940,117 @@ void t_cpp_generator::generate_cpp_struct(t_struct* tstruct, bool is_exception) | ||
| 62 | has_members_ = true; | ||
| 63 | } | ||
| 64 | |||
| 65 | +void t_cpp_generator::generate_equality_operator(std::ostream& out, t_struct* tstruct) { | ||
| 66 | + // Get members | ||
| 67 | + vector<t_field*>::const_iterator m_iter; | ||
| 68 | + const vector<t_field*>& members = tstruct->get_members(); | ||
| 69 | + | ||
| 70 | + out << indent() << "bool " << tstruct->get_name() | ||
| 71 | + << "::operator==(const " << tstruct->get_name() << " & " | ||
| 72 | + << (members.size() > 0 ? "rhs" : "/* rhs */") << ") const" << endl; | ||
| 73 | + scope_up(out); | ||
| 74 | + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { | ||
| 75 | + // Most existing Thrift code does not use isset or optional/required, | ||
| 76 | + // so we treat "default" fields as required. | ||
| 77 | + if ((*m_iter)->get_req() != t_field::T_OPTIONAL) { | ||
| 78 | + out << indent() << "if (!(" << (*m_iter)->get_name() << " == rhs." | ||
| 79 | + << (*m_iter)->get_name() << "))" << endl << indent() << " return false;" << endl; | ||
| 80 | + } else { | ||
| 81 | + out << indent() << "if (__isset." << (*m_iter)->get_name() << " != rhs.__isset." | ||
| 82 | + << (*m_iter)->get_name() << ")" << endl << indent() << " return false;" << endl | ||
| 83 | + << indent() << "else if (__isset." << (*m_iter)->get_name() << " && !(" | ||
| 84 | + << (*m_iter)->get_name() << " == rhs." << (*m_iter)->get_name() << "))" << endl | ||
| 85 | + << indent() << " return false;" << endl; | ||
| 86 | + } | ||
| 87 | + } | ||
| 88 | + indent(out) << "return true;" << endl; | ||
| 89 | + scope_down(out); | ||
| 90 | + out << "\n"; | ||
| 91 | +} | ||
| 92 | + | ||
| 93 | +void t_cpp_generator::generate_default_constructor(ostream& out, | ||
| 94 | + t_struct* tstruct, | ||
| 95 | + bool is_exception) { | ||
| 96 | + // Get members | ||
| 97 | + vector<t_field*>::const_iterator m_iter; | ||
| 98 | + const vector<t_field*>& members = tstruct->get_members(); | ||
| 99 | + | ||
| 100 | + // TODO(barth) this is duplicated from generate_struct_declaration | ||
| 101 | + bool has_default_value = false; | ||
| 102 | + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { | ||
| 103 | + t_type* t = get_true_type((*m_iter)->get_type()); | ||
| 104 | + if (is_reference(*m_iter) || t->is_string()) { | ||
| 105 | + t_const_value* cv = (*m_iter)->get_value(); | ||
| 106 | + if (cv != nullptr) { | ||
| 107 | + has_default_value = true; | ||
| 108 | + break; | ||
| 109 | + } | ||
| 110 | + } | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + std::string clsname_ctor = tstruct->get_name() + "::" + tstruct->get_name() + "()"; | ||
| 114 | + indent(out) << clsname_ctor << (has_default_value ? "" : " noexcept"); | ||
| 115 | + | ||
| 116 | + if (has_default_value || is_exception) { | ||
| 117 | + // We need an initializer block | ||
| 118 | + | ||
| 119 | + bool init_ctor = false; | ||
| 120 | + std::string args_indent(" "); | ||
| 121 | + | ||
| 122 | + // Default-initialize TException, if it is our base type | ||
| 123 | + if (is_exception) | ||
| 124 | + { | ||
| 125 | + out << "\n"; | ||
| 126 | + indent(out) << " : "; | ||
| 127 | + out << "TException()"; | ||
| 128 | + init_ctor = true; | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + // Default-initialize all members that should be initialized in | ||
| 132 | + // the initializer block | ||
| 133 | + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { | ||
| 134 | + t_type* t = get_true_type((*m_iter)->get_type()); | ||
| 135 | + if (t->is_base_type() || t->is_enum() || is_reference(*m_iter)) { | ||
| 136 | + string dval; | ||
| 137 | + t_const_value* cv = (*m_iter)->get_value(); | ||
| 138 | + if (cv != nullptr) { | ||
| 139 | + dval += render_const_value(out, (*m_iter)->get_name(), t, cv); | ||
| 140 | + } else if (t->is_enum()) { | ||
| 141 | + dval += "static_cast<" + type_name(t) + ">(0)"; | ||
| 142 | + } else { | ||
| 143 | + dval += (t->is_string() || is_reference(*m_iter)) ? "" : "0"; | ||
| 144 | + } | ||
| 145 | + if (!init_ctor) { | ||
| 146 | + out << "\n"; | ||
| 147 | + indent(out) << " : "; | ||
| 148 | + init_ctor = true; | ||
| 149 | + } else { | ||
| 150 | + out << ",\n"; | ||
| 151 | + indent(out) << args_indent; | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + out << (*m_iter)->get_name() << "(" << dval << ")"; | ||
| 155 | + } | ||
| 156 | + } | ||
| 157 | + out << " {" << endl; | ||
| 158 | + indent_up(); | ||
| 159 | + // TODO(dreiss): When everything else in Thrift is perfect, | ||
| 160 | + // do more of these in the initializer list. | ||
| 161 | + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { | ||
| 162 | + t_type* t = get_true_type((*m_iter)->get_type()); | ||
| 163 | + if (!t->is_base_type() && !t->is_enum() && !is_reference(*m_iter)) { | ||
| 164 | + t_const_value* cv = (*m_iter)->get_value(); | ||
| 165 | + if (cv != nullptr) { | ||
| 166 | + print_const_value(out, (*m_iter)->get_name(), t, cv); | ||
| 167 | + } | ||
| 168 | + } | ||
| 169 | + } | ||
| 170 | + scope_down(out); | ||
| 171 | + } else { | ||
| 172 | + out << " {}\n"; | ||
| 173 | + } | ||
| 174 | +} | ||
| 175 | + | ||
| 176 | void t_cpp_generator::generate_copy_constructor(ostream& out, | ||
| 177 | t_struct* tstruct, | ||
| 178 | bool is_exception) { | ||
| 179 | @@ -1168,52 +1285,7 @@ void t_cpp_generator::generate_struct_declaration(ostream& out, | ||
| 180 | |||
| 181 | // Default constructor | ||
| 182 | std::string clsname_ctor = tstruct->get_name() + "()"; | ||
| 183 | - indent(out) << clsname_ctor << (has_default_value ? "" : " noexcept"); | ||
| 184 | - | ||
| 185 | - bool init_ctor = false; | ||
| 186 | - std::string args_indent( | ||
| 187 | - indent().size() + clsname_ctor.size() + (has_default_value ? 3 : -1), ' '); | ||
| 188 | - | ||
| 189 | - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { | ||
| 190 | - t_type* t = get_true_type((*m_iter)->get_type()); | ||
| 191 | - if (t->is_base_type() || t->is_enum() || is_reference(*m_iter)) { | ||
| 192 | - string dval; | ||
| 193 | - t_const_value* cv = (*m_iter)->get_value(); | ||
| 194 | - if (cv != nullptr) { | ||
| 195 | - dval += render_const_value(out, (*m_iter)->get_name(), t, cv); | ||
| 196 | - } else if (t->is_enum()) { | ||
| 197 | - dval += "static_cast<" + type_name(t) + ">(0)"; | ||
| 198 | - } else { | ||
| 199 | - dval += (t->is_string() || is_reference(*m_iter)) ? "" : "0"; | ||
| 200 | - } | ||
| 201 | - if (!init_ctor) { | ||
| 202 | - init_ctor = true; | ||
| 203 | - if(has_default_value) { | ||
| 204 | - out << " : "; | ||
| 205 | - } else { | ||
| 206 | - out << '\n' << args_indent << ": "; | ||
| 207 | - args_indent.append(" "); | ||
| 208 | - } | ||
| 209 | - } else { | ||
| 210 | - out << ",\n" << args_indent; | ||
| 211 | - } | ||
| 212 | - out << (*m_iter)->get_name() << "(" << dval << ")"; | ||
| 213 | - } | ||
| 214 | - } | ||
| 215 | - out << " {" << endl; | ||
| 216 | - indent_up(); | ||
| 217 | - // TODO(dreiss): When everything else in Thrift is perfect, | ||
| 218 | - // do more of these in the initializer list. | ||
| 219 | - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { | ||
| 220 | - t_type* t = get_true_type((*m_iter)->get_type()); | ||
| 221 | - if (!t->is_base_type() && !t->is_enum() && !is_reference(*m_iter)) { | ||
| 222 | - t_const_value* cv = (*m_iter)->get_value(); | ||
| 223 | - if (cv != nullptr) { | ||
| 224 | - print_const_value(out, (*m_iter)->get_name(), t, cv); | ||
| 225 | - } | ||
| 226 | - } | ||
| 227 | - } | ||
| 228 | - scope_down(out); | ||
| 229 | + indent(out) << clsname_ctor << (has_default_value ? "" : " noexcept") << ";" << endl; | ||
| 230 | } | ||
| 231 | |||
| 232 | if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) { | ||
| 233 | @@ -1254,27 +1326,10 @@ void t_cpp_generator::generate_struct_declaration(ostream& out, | ||
| 234 | if (!pointers) { | ||
| 235 | // Should we generate default operators? | ||
| 236 | if (!gen_no_default_operators_) { | ||
| 237 | - // Generate an equality testing operator. Make it inline since the compiler | ||
| 238 | - // will do a better job than we would when deciding whether to inline it. | ||
| 239 | + // Generate an equality testing operator. | ||
| 240 | out << indent() << "bool operator == (const " << tstruct->get_name() << " & " | ||
| 241 | - << (members.size() > 0 ? "rhs" : "/* rhs */") << ") const" << endl; | ||
| 242 | - scope_up(out); | ||
| 243 | - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { | ||
| 244 | - // Most existing Thrift code does not use isset or optional/required, | ||
| 245 | - // so we treat "default" fields as required. | ||
| 246 | - if ((*m_iter)->get_req() != t_field::T_OPTIONAL) { | ||
| 247 | - out << indent() << "if (!(" << (*m_iter)->get_name() << " == rhs." | ||
| 248 | - << (*m_iter)->get_name() << "))" << endl << indent() << " return false;" << endl; | ||
| 249 | - } else { | ||
| 250 | - out << indent() << "if (__isset." << (*m_iter)->get_name() << " != rhs.__isset." | ||
| 251 | - << (*m_iter)->get_name() << ")" << endl << indent() << " return false;" << endl | ||
| 252 | - << indent() << "else if (__isset." << (*m_iter)->get_name() << " && !(" | ||
| 253 | - << (*m_iter)->get_name() << " == rhs." << (*m_iter)->get_name() << "))" << endl | ||
| 254 | - << indent() << " return false;" << endl; | ||
| 255 | - } | ||
| 256 | - } | ||
| 257 | - indent(out) << "return true;" << endl; | ||
| 258 | - scope_down(out); | ||
| 259 | + << (members.size() > 0 ? "rhs" : "/* rhs */") << ") const;" << endl; | ||
| 260 | + | ||
| 261 | out << indent() << "bool operator != (const " << tstruct->get_name() << " &rhs) const {" | ||
| 262 | << endl << indent() << " return !(*this == rhs);" << endl << indent() << "}" << endl | ||
| 263 | << endl; | ||
| 264 | |||
| 265 | From cedcd0e6424a08dd6feeb2533810054c9aca2a9e Mon Sep 17 00:00:00 2001 | ||
| 266 | From: Lukas Barth <mail@tinloaf.de> | ||
| 267 | Date: Wed, 8 Feb 2023 10:11:48 +0100 | ||
| 268 | Subject: [PATCH 2/5] Factor out duplicated code into helper function | ||
| 269 | |||
| 270 | --- | ||
| 271 | .../src/thrift/generate/t_cpp_generator.cc | 43 ++++++++++--------- | ||
| 272 | 1 file changed, 23 insertions(+), 20 deletions(-) | ||
| 273 | |||
| 274 | diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc | ||
| 275 | index fecfa4bb5..a77982f61 100644 | ||
| 276 | --- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc | ||
| 277 | +++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc | ||
| 278 | @@ -302,6 +302,12 @@ public: | ||
| 279 | */ | ||
| 280 | bool is_struct_storage_not_throwing(t_struct* tstruct) const; | ||
| 281 | |||
| 282 | + /** | ||
| 283 | + * Helper function to determine whether any of the members of our struct | ||
| 284 | + * has a default value. | ||
| 285 | + */ | ||
| 286 | + bool has_field_with_default_value(t_struct* tstruct); | ||
| 287 | + | ||
| 288 | private: | ||
| 289 | /** | ||
| 290 | * Returns the include prefix to use for a file generated by program, or the | ||
| 291 | @@ -968,26 +974,33 @@ void t_cpp_generator::generate_equality_operator(std::ostream& out, t_struct* ts | ||
| 292 | out << "\n"; | ||
| 293 | } | ||
| 294 | |||
| 295 | -void t_cpp_generator::generate_default_constructor(ostream& out, | ||
| 296 | - t_struct* tstruct, | ||
| 297 | - bool is_exception) { | ||
| 298 | - // Get members | ||
| 299 | +bool t_cpp_generator::has_field_with_default_value(t_struct* tstruct) | ||
| 300 | +{ | ||
| 301 | vector<t_field*>::const_iterator m_iter; | ||
| 302 | const vector<t_field*>& members = tstruct->get_members(); | ||
| 303 | |||
| 304 | - // TODO(barth) this is duplicated from generate_struct_declaration | ||
| 305 | - bool has_default_value = false; | ||
| 306 | for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { | ||
| 307 | t_type* t = get_true_type((*m_iter)->get_type()); | ||
| 308 | if (is_reference(*m_iter) || t->is_string()) { | ||
| 309 | t_const_value* cv = (*m_iter)->get_value(); | ||
| 310 | if (cv != nullptr) { | ||
| 311 | - has_default_value = true; | ||
| 312 | - break; | ||
| 313 | + return true; | ||
| 314 | } | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | + return false; | ||
| 319 | +} | ||
| 320 | + | ||
| 321 | +void t_cpp_generator::generate_default_constructor(ostream& out, | ||
| 322 | + t_struct* tstruct, | ||
| 323 | + bool is_exception) { | ||
| 324 | + // Get members | ||
| 325 | + vector<t_field*>::const_iterator m_iter; | ||
| 326 | + const vector<t_field*>& members = tstruct->get_members(); | ||
| 327 | + | ||
| 328 | + bool has_default_value = has_field_with_default_value(tstruct); | ||
| 329 | + | ||
| 330 | std::string clsname_ctor = tstruct->get_name() + "::" + tstruct->get_name() + "()"; | ||
| 331 | indent(out) << clsname_ctor << (has_default_value ? "" : " noexcept"); | ||
| 332 | |||
| 333 | @@ -1271,18 +1284,8 @@ void t_cpp_generator::generate_struct_declaration(ostream& out, | ||
| 334 | << endl; | ||
| 335 | } | ||
| 336 | |||
| 337 | - bool has_default_value = false; | ||
| 338 | - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { | ||
| 339 | - t_type* t = get_true_type((*m_iter)->get_type()); | ||
| 340 | - if (is_reference(*m_iter) || t->is_string()) { | ||
| 341 | - t_const_value* cv = (*m_iter)->get_value(); | ||
| 342 | - if (cv != nullptr) { | ||
| 343 | - has_default_value = true; | ||
| 344 | - break; | ||
| 345 | - } | ||
| 346 | - } | ||
| 347 | - } | ||
| 348 | - | ||
| 349 | + bool has_default_value = has_field_with_default_value(tstruct); | ||
| 350 | + | ||
| 351 | // Default constructor | ||
| 352 | std::string clsname_ctor = tstruct->get_name() + "()"; | ||
| 353 | indent(out) << clsname_ctor << (has_default_value ? "" : " noexcept") << ";" << endl; | ||
| 354 | |||
| 355 | From 16105fa1a1bb9ae633b805fcb7af3c7757beb6e0 Mon Sep 17 00:00:00 2001 | ||
| 356 | From: Lukas Barth <mail@tinloaf.de> | ||
| 357 | Date: Fri, 24 Feb 2023 13:46:58 +0100 | ||
| 358 | Subject: [PATCH 3/5] Move generate_default_constructor call into | ||
| 359 | generate_struct_definition | ||
| 360 | |||
| 361 | This makes sure that helper structs like _args and _result also have | ||
| 362 | their default constructors defined. | ||
| 363 | --- | ||
| 364 | .../src/thrift/generate/t_cpp_generator.cc | 19 +++++++++++++------ | ||
| 365 | 1 file changed, 13 insertions(+), 6 deletions(-) | ||
| 366 | |||
| 367 | diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc | ||
| 368 | index a77982f61..ccb79bc48 100644 | ||
| 369 | --- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc | ||
| 370 | +++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc | ||
| 371 | @@ -143,7 +143,8 @@ public: | ||
| 372 | std::ostream& force_cpp_out, | ||
| 373 | t_struct* tstruct, | ||
| 374 | bool setters = true, | ||
| 375 | - bool is_user_struct = false); | ||
| 376 | + bool is_user_struct = false, | ||
| 377 | + bool pointers = false); | ||
| 378 | void generate_copy_constructor(std::ostream& out, t_struct* tstruct, bool is_exception); | ||
| 379 | void generate_move_constructor(std::ostream& out, t_struct* tstruct, bool is_exception); | ||
| 380 | void generate_default_constructor(std::ostream& out, t_struct* tstruct, bool is_exception); | ||
| 381 | @@ -916,7 +917,7 @@ void t_cpp_generator::generate_forward_declaration(t_struct* tstruct) { | ||
| 382 | */ | ||
| 383 | void t_cpp_generator::generate_cpp_struct(t_struct* tstruct, bool is_exception) { | ||
| 384 | generate_struct_declaration(f_types_, tstruct, is_exception, false, true, true, true, true); | ||
| 385 | - generate_struct_definition(f_types_impl_, f_types_impl_, tstruct, true, true); | ||
| 386 | + generate_struct_definition(f_types_impl_, f_types_impl_, tstruct, true, true, false); | ||
| 387 | |||
| 388 | std::ostream& out = (gen_templates_ ? f_types_tcc_ : f_types_impl_); | ||
| 389 | generate_struct_reader(out, tstruct); | ||
| 390 | @@ -925,7 +926,6 @@ void t_cpp_generator::generate_cpp_struct(t_struct* tstruct, bool is_exception) | ||
| 391 | if (!gen_no_default_operators_) { | ||
| 392 | generate_equality_operator(f_types_impl_, tstruct); | ||
| 393 | } | ||
| 394 | - generate_default_constructor(f_types_impl_, tstruct, is_exception); | ||
| 395 | generate_copy_constructor(f_types_impl_, tstruct, is_exception); | ||
| 396 | if (gen_moveable_) { | ||
| 397 | generate_move_constructor(f_types_impl_, tstruct, is_exception); | ||
| 398 | @@ -1408,7 +1408,8 @@ void t_cpp_generator::generate_struct_definition(ostream& out, | ||
| 399 | ostream& force_cpp_out, | ||
| 400 | t_struct* tstruct, | ||
| 401 | bool setters, | ||
| 402 | - bool is_user_struct) { | ||
| 403 | + bool is_user_struct, | ||
| 404 | + bool pointers) { | ||
| 405 | // Get members | ||
| 406 | vector<t_field*>::const_iterator m_iter; | ||
| 407 | const vector<t_field*>& members = tstruct->get_members(); | ||
| 408 | @@ -1423,6 +1424,11 @@ void t_cpp_generator::generate_struct_definition(ostream& out, | ||
| 409 | force_cpp_out << indent() << "}" << endl << endl; | ||
| 410 | } | ||
| 411 | |||
| 412 | + if (!pointers) | ||
| 413 | + { | ||
| 414 | + generate_default_constructor(out, tstruct, false); | ||
| 415 | + } | ||
| 416 | + | ||
| 417 | // Create a setter function for each field | ||
| 418 | if (setters) { | ||
| 419 | for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { | ||
| 420 | @@ -2058,9 +2064,10 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) { | ||
| 421 | generate_struct_definition(out, f_service_, ts, false); | ||
| 422 | generate_struct_reader(out, ts); | ||
| 423 | generate_struct_writer(out, ts); | ||
| 424 | + | ||
| 425 | ts->set_name(tservice->get_name() + "_" + (*f_iter)->get_name() + "_pargs"); | ||
| 426 | generate_struct_declaration(f_header_, ts, false, true, false, true); | ||
| 427 | - generate_struct_definition(out, f_service_, ts, false); | ||
| 428 | + generate_struct_definition(out, f_service_, ts, false, false, true); | ||
| 429 | generate_struct_writer(out, ts, true); | ||
| 430 | ts->set_name(name_orig); | ||
| 431 | |||
| 432 | @@ -3508,7 +3515,7 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function* | ||
| 433 | |||
| 434 | result.set_name(tservice->get_name() + "_" + tfunction->get_name() + "_presult"); | ||
| 435 | generate_struct_declaration(f_header_, &result, false, true, true, gen_cob_style_); | ||
| 436 | - generate_struct_definition(out, f_service_, &result, false); | ||
| 437 | + generate_struct_definition(out, f_service_, &result, false, false, true); | ||
| 438 | generate_struct_reader(out, &result, true); | ||
| 439 | if (gen_cob_style_) { | ||
| 440 | generate_struct_writer(out, &result, true); | ||
| 441 | |||
| 442 | From 4f56007baf46d4aa87eb7f8e5e34b773235c729a Mon Sep 17 00:00:00 2001 | ||
| 443 | From: Lukas Barth <mail@tinloaf.de> | ||
| 444 | Date: Mon, 6 Mar 2023 11:37:09 +0100 | ||
| 445 | Subject: [PATCH 4/5] Always generate an initializer list | ||
| 446 | |||
| 447 | --- | ||
| 448 | .../src/thrift/generate/t_cpp_generator.cc | 102 +++++++++--------- | ||
| 449 | 1 file changed, 54 insertions(+), 48 deletions(-) | ||
| 450 | |||
| 451 | diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc | ||
| 452 | index ccb79bc48..2a65bfb96 100644 | ||
| 453 | --- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc | ||
| 454 | +++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc | ||
| 455 | @@ -1004,64 +1004,70 @@ void t_cpp_generator::generate_default_constructor(ostream& out, | ||
| 456 | std::string clsname_ctor = tstruct->get_name() + "::" + tstruct->get_name() + "()"; | ||
| 457 | indent(out) << clsname_ctor << (has_default_value ? "" : " noexcept"); | ||
| 458 | |||
| 459 | - if (has_default_value || is_exception) { | ||
| 460 | - // We need an initializer block | ||
| 461 | + // | ||
| 462 | + // Start generating initializer list | ||
| 463 | + // | ||
| 464 | |||
| 465 | - bool init_ctor = false; | ||
| 466 | - std::string args_indent(" "); | ||
| 467 | + bool init_ctor = false; | ||
| 468 | + std::string args_indent(" "); | ||
| 469 | |||
| 470 | - // Default-initialize TException, if it is our base type | ||
| 471 | - if (is_exception) | ||
| 472 | - { | ||
| 473 | - out << "\n"; | ||
| 474 | - indent(out) << " : "; | ||
| 475 | - out << "TException()"; | ||
| 476 | - init_ctor = true; | ||
| 477 | - } | ||
| 478 | + // Default-initialize TException, if it is our base type | ||
| 479 | + if (is_exception) | ||
| 480 | + { | ||
| 481 | + out << "\n"; | ||
| 482 | + indent(out) << " : "; | ||
| 483 | + out << "TException()"; | ||
| 484 | + init_ctor = true; | ||
| 485 | + } | ||
| 486 | |||
| 487 | - // Default-initialize all members that should be initialized in | ||
| 488 | - // the initializer block | ||
| 489 | - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { | ||
| 490 | - t_type* t = get_true_type((*m_iter)->get_type()); | ||
| 491 | - if (t->is_base_type() || t->is_enum() || is_reference(*m_iter)) { | ||
| 492 | - string dval; | ||
| 493 | - t_const_value* cv = (*m_iter)->get_value(); | ||
| 494 | - if (cv != nullptr) { | ||
| 495 | - dval += render_const_value(out, (*m_iter)->get_name(), t, cv); | ||
| 496 | - } else if (t->is_enum()) { | ||
| 497 | - dval += "static_cast<" + type_name(t) + ">(0)"; | ||
| 498 | - } else { | ||
| 499 | - dval += (t->is_string() || is_reference(*m_iter)) ? "" : "0"; | ||
| 500 | - } | ||
| 501 | - if (!init_ctor) { | ||
| 502 | - out << "\n"; | ||
| 503 | - indent(out) << " : "; | ||
| 504 | - init_ctor = true; | ||
| 505 | + // Default-initialize all members that should be initialized in | ||
| 506 | + // the initializer block | ||
| 507 | + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { | ||
| 508 | + t_type* t = get_true_type((*m_iter)->get_type()); | ||
| 509 | + if (t->is_base_type() || t->is_enum() || is_reference(*m_iter)) { | ||
| 510 | + string dval; | ||
| 511 | + t_const_value* cv = (*m_iter)->get_value(); | ||
| 512 | + if (cv != nullptr) { | ||
| 513 | + dval += render_const_value(out, (*m_iter)->get_name(), t, cv); | ||
| 514 | + } else if (t->is_enum()) { | ||
| 515 | + dval += "static_cast<" + type_name(t) + ">(0)"; | ||
| 516 | + } else { | ||
| 517 | + dval += (t->is_string() || is_reference(*m_iter)) ? "" : "0"; | ||
| 518 | + } | ||
| 519 | + if (!init_ctor) { | ||
| 520 | + init_ctor = true; | ||
| 521 | + if(has_default_value) { | ||
| 522 | + out << " : "; | ||
| 523 | } else { | ||
| 524 | - out << ",\n"; | ||
| 525 | - indent(out) << args_indent; | ||
| 526 | + out << '\n' << args_indent << ": "; | ||
| 527 | + args_indent.append(" "); | ||
| 528 | } | ||
| 529 | - | ||
| 530 | - out << (*m_iter)->get_name() << "(" << dval << ")"; | ||
| 531 | + } else { | ||
| 532 | + out << ",\n" << args_indent; | ||
| 533 | } | ||
| 534 | + | ||
| 535 | + out << (*m_iter)->get_name() << "(" << dval << ")"; | ||
| 536 | } | ||
| 537 | - out << " {" << endl; | ||
| 538 | - indent_up(); | ||
| 539 | - // TODO(dreiss): When everything else in Thrift is perfect, | ||
| 540 | - // do more of these in the initializer list. | ||
| 541 | - for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { | ||
| 542 | - t_type* t = get_true_type((*m_iter)->get_type()); | ||
| 543 | - if (!t->is_base_type() && !t->is_enum() && !is_reference(*m_iter)) { | ||
| 544 | - t_const_value* cv = (*m_iter)->get_value(); | ||
| 545 | - if (cv != nullptr) { | ||
| 546 | - print_const_value(out, (*m_iter)->get_name(), t, cv); | ||
| 547 | - } | ||
| 548 | + } | ||
| 549 | + | ||
| 550 | + // | ||
| 551 | + // Start generating body | ||
| 552 | + // | ||
| 553 | + | ||
| 554 | + out << " {" << endl; | ||
| 555 | + indent_up(); | ||
| 556 | + // TODO(dreiss): When everything else in Thrift is perfect, | ||
| 557 | + // do more of these in the initializer list. | ||
| 558 | + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { | ||
| 559 | + t_type* t = get_true_type((*m_iter)->get_type()); | ||
| 560 | + if (!t->is_base_type() && !t->is_enum() && !is_reference(*m_iter)) { | ||
| 561 | + t_const_value* cv = (*m_iter)->get_value(); | ||
| 562 | + if (cv != nullptr) { | ||
| 563 | + print_const_value(out, (*m_iter)->get_name(), t, cv); | ||
| 564 | } | ||
| 565 | } | ||
| 566 | - scope_down(out); | ||
| 567 | - } else { | ||
| 568 | - out << " {}\n"; | ||
| 569 | } | ||
| 570 | + scope_down(out); | ||
| 571 | } | ||
| 572 | |||
| 573 | void t_cpp_generator::generate_copy_constructor(ostream& out, | ||
| 574 | |||
| 575 | From 9bd8f1e1acb23cb3ef134291e56b2605a7356b04 Mon Sep 17 00:00:00 2001 | ||
| 576 | From: Lukas Barth <mail@tinloaf.de> | ||
| 577 | Date: Tue, 4 Apr 2023 16:25:06 +0200 | ||
| 578 | Subject: [PATCH 5/5] Fix ODR violations in cases where templates are involved | ||
| 579 | |||
| 580 | --- | ||
| 581 | compiler/cpp/src/thrift/generate/t_cpp_generator.cc | 5 ++++- | ||
| 582 | 1 file changed, 4 insertions(+), 1 deletion(-) | ||
| 583 | |||
| 584 | diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc | ||
| 585 | index 2a65bfb96..a085ada0e 100644 | ||
| 586 | --- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc | ||
| 587 | +++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc | ||
| 588 | @@ -1432,7 +1432,10 @@ void t_cpp_generator::generate_struct_definition(ostream& out, | ||
| 589 | |||
| 590 | if (!pointers) | ||
| 591 | { | ||
| 592 | - generate_default_constructor(out, tstruct, false); | ||
| 593 | + // 'force_cpp_out' always goes into the .cpp file, and never into a .tcc | ||
| 594 | + // file in case templates are involved. Since the constructor is not templated, | ||
| 595 | + // putting it into the (later included) .tcc file would cause ODR violations. | ||
| 596 | + generate_default_constructor(force_cpp_out, tstruct, false); | ||
| 597 | } | ||
| 598 | |||
| 599 | // Create a setter function for each field | ||
diff --git a/meta-oe/recipes-connectivity/thrift/thrift_0.20.0.bb b/meta-oe/recipes-connectivity/thrift/thrift_0.20.0.bb index 23db052b9e..c908eab7b3 100644 --- a/meta-oe/recipes-connectivity/thrift/thrift_0.20.0.bb +++ b/meta-oe/recipes-connectivity/thrift/thrift_0.20.0.bb | |||
| @@ -9,7 +9,9 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=c40a383cb3f747e0c7abbf1482f194f0 \ | |||
| 9 | DEPENDS = "thrift-native boost flex-native bison-native openssl zlib" | 9 | DEPENDS = "thrift-native boost flex-native bison-native openssl zlib" |
| 10 | 10 | ||
| 11 | SRC_URI = "https://downloads.apache.org/${BPN}/${PV}/${BP}.tar.gz \ | 11 | SRC_URI = "https://downloads.apache.org/${BPN}/${PV}/${BP}.tar.gz \ |
| 12 | file://0001-DefineInstallationPaths.cmake-Define-libdir-in-terms.patch" | 12 | file://0001-DefineInstallationPaths.cmake-Define-libdir-in-terms.patch \ |
| 13 | file://0001-thrift-pr2755.patch \ | ||
| 14 | " | ||
| 13 | SRC_URI[sha256sum] = "b5d8311a779470e1502c027f428a1db542f5c051c8e1280ccd2163fa935ff2d6" | 15 | SRC_URI[sha256sum] = "b5d8311a779470e1502c027f428a1db542f5c051c8e1280ccd2163fa935ff2d6" |
| 14 | 16 | ||
| 15 | BBCLASSEXTEND = "native nativesdk" | 17 | BBCLASSEXTEND = "native nativesdk" |
