|
|
@ -2397,7 +2397,7 @@ void MessageGenerator::GenerateInitDefaultSplitInstance(io::Printer* p) { |
|
|
|
|
|
|
|
|
|
|
|
void MessageGenerator::GenerateSharedDestructorCode(io::Printer* p) { |
|
|
|
void MessageGenerator::GenerateSharedDestructorCode(io::Printer* p) { |
|
|
|
if (HasSimpleBaseClass(descriptor_, options_)) return; |
|
|
|
if (HasSimpleBaseClass(descriptor_, options_)) return; |
|
|
|
auto emit_fields_dtors = [&](bool split_fields) { |
|
|
|
auto emit_field_dtors = [&](bool split_fields) { |
|
|
|
// Write the destructors for each field except oneof members.
|
|
|
|
// Write the destructors for each field except oneof members.
|
|
|
|
// optimized_order_ does not contain oneof fields.
|
|
|
|
// optimized_order_ does not contain oneof fields.
|
|
|
|
for (const auto* field : optimized_order_) { |
|
|
|
for (const auto* field : optimized_order_) { |
|
|
@ -2414,15 +2414,14 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* p) { |
|
|
|
$extensions$.~ExtensionSet(); |
|
|
|
$extensions$.~ExtensionSet(); |
|
|
|
)cc"); |
|
|
|
)cc"); |
|
|
|
}}, |
|
|
|
}}, |
|
|
|
{"field_dtors", |
|
|
|
{"field_dtors", [&] { emit_field_dtors(/* split_fields= */ false); }}, |
|
|
|
[&] { emit_fields_dtors(/* split_fields= */ false); }}, |
|
|
|
|
|
|
|
{"split_field_dtors", |
|
|
|
{"split_field_dtors", |
|
|
|
[&] { |
|
|
|
[&] { |
|
|
|
if (!ShouldSplit(descriptor_, options_)) return; |
|
|
|
if (!ShouldSplit(descriptor_, options_)) return; |
|
|
|
p->Emit( |
|
|
|
p->Emit( |
|
|
|
{ |
|
|
|
{ |
|
|
|
{"split_field_dtors_impl", |
|
|
|
{"split_field_dtors_impl", |
|
|
|
[&] { emit_fields_dtors(/* split_fields= */ true); }}, |
|
|
|
[&] { emit_field_dtors(/* split_fields= */ true); }}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
R"cc( |
|
|
|
R"cc( |
|
|
|
if (!IsSplitMessageDefault()) { |
|
|
|
if (!IsSplitMessageDefault()) { |
|
|
@ -2484,45 +2483,52 @@ ArenaDtorNeeds MessageGenerator::NeedsArenaDestructor() const { |
|
|
|
|
|
|
|
|
|
|
|
void MessageGenerator::GenerateArenaDestructorCode(io::Printer* p) { |
|
|
|
void MessageGenerator::GenerateArenaDestructorCode(io::Printer* p) { |
|
|
|
ABSL_CHECK(NeedsArenaDestructor() > ArenaDtorNeeds::kNone); |
|
|
|
ABSL_CHECK(NeedsArenaDestructor() > ArenaDtorNeeds::kNone); |
|
|
|
|
|
|
|
auto emit_field_dtors = [&](bool split_fields) { |
|
|
|
Formatter format(p); |
|
|
|
// Write the destructors for each field except oneof members.
|
|
|
|
|
|
|
|
// optimized_order_ does not contain oneof fields.
|
|
|
|
// Generate the ArenaDtor() method. Track whether any fields actually produced
|
|
|
|
for (const auto* field : optimized_order_) { |
|
|
|
// code that needs to be called.
|
|
|
|
if (ShouldSplit(field, options_) != split_fields) continue; |
|
|
|
format("void $classname$::ArenaDtor(void* object) {\n"); |
|
|
|
field_generators_.get(field).GenerateArenaDestructorCode(p); |
|
|
|
format.Indent(); |
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
// This code is placed inside a static method, rather than an ordinary one,
|
|
|
|
// This code is placed inside a static method, rather than an ordinary one,
|
|
|
|
// since that simplifies Arena's destructor list (ordinary function pointers
|
|
|
|
// since that simplifies Arena's destructor list (ordinary function pointers
|
|
|
|
// rather than member function pointers). _this is the object being
|
|
|
|
// rather than member function pointers). _this is the object being
|
|
|
|
// destructed.
|
|
|
|
// destructed.
|
|
|
|
format("$classname$* _this = reinterpret_cast< $classname$* >(object);\n"); |
|
|
|
p->Emit( |
|
|
|
|
|
|
|
{ |
|
|
|
// Process non-oneof fields first.
|
|
|
|
{"field_dtors", [&] { emit_field_dtors(/* split_fields= */ false); }}, |
|
|
|
for (auto field : optimized_order_) { |
|
|
|
{"split_field_dtors", |
|
|
|
if (ShouldSplit(field, options_)) continue; |
|
|
|
[&] { |
|
|
|
field_generators_.get(field).GenerateArenaDestructorCode(p); |
|
|
|
if (!ShouldSplit(descriptor_, options_)) return; |
|
|
|
} |
|
|
|
p->Emit( |
|
|
|
if (ShouldSplit(descriptor_, options_)) { |
|
|
|
{ |
|
|
|
format("if (!_this->IsSplitMessageDefault()) {\n"); |
|
|
|
{"split_field_dtors_impl", |
|
|
|
format.Indent(); |
|
|
|
[&] { emit_field_dtors(/* split_fields= */ true); }}, |
|
|
|
for (auto field : optimized_order_) { |
|
|
|
}, |
|
|
|
if (!ShouldSplit(field, options_)) continue; |
|
|
|
R"cc( |
|
|
|
field_generators_.get(field).GenerateArenaDestructorCode(p); |
|
|
|
if (!_this->IsSplitMessageDefault()) { |
|
|
|
} |
|
|
|
$split_field_dtors_impl$; |
|
|
|
format.Outdent(); |
|
|
|
} |
|
|
|
format("}\n"); |
|
|
|
)cc"); |
|
|
|
} |
|
|
|
}}, |
|
|
|
|
|
|
|
{"oneof_field_dtors", |
|
|
|
// Process oneof fields.
|
|
|
|
[&] { |
|
|
|
for (auto oneof : OneOfRange(descriptor_)) { |
|
|
|
for (const auto* oneof : OneOfRange(descriptor_)) { |
|
|
|
for (auto field : FieldRange(oneof)) { |
|
|
|
for (const auto* field : FieldRange(oneof)) { |
|
|
|
field_generators_.get(field).GenerateArenaDestructorCode(p); |
|
|
|
field_generators_.get(field).GenerateArenaDestructorCode(p); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
}}, |
|
|
|
format.Outdent(); |
|
|
|
}, |
|
|
|
format("}\n"); |
|
|
|
R"cc( |
|
|
|
|
|
|
|
void $classname$::ArenaDtor(void* object) { |
|
|
|
|
|
|
|
$classname$* _this = reinterpret_cast<$classname$*>(object); |
|
|
|
|
|
|
|
$field_dtors$; |
|
|
|
|
|
|
|
$split_field_dtors$; |
|
|
|
|
|
|
|
$oneof_field_dtors$; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
)cc"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void MessageGenerator::GenerateConstexprConstructor(io::Printer* p) { |
|
|
|
void MessageGenerator::GenerateConstexprConstructor(io::Printer* p) { |
|
|
|