diff options
author | Jisi Liu <jisi.liu@gmail.com> | 2015-02-28 14:51:22 -0800 |
---|---|---|
committer | Jisi Liu <jisi.liu@gmail.com> | 2015-02-28 17:06:49 -0800 |
commit | 885b612f74f133678bf82808c589331e4c59dad9 (patch) | |
tree | e5f3f65b41af477c52810053b8694896c8bcd1f7 /src/google/protobuf/compiler/cpp | |
parent | 1939efed2db35020b7830a4927f10feac47b6757 (diff) |
Down integrate from Google internal branch for C++ and Java.
- Maps for C++ lite
- C++ Arena optimizations.
- Java Lite runtime code size optimization.
Change-Id: I7537a4357c1cb385d23f9e8aa7ffdfeefe079f13
Diffstat (limited to 'src/google/protobuf/compiler/cpp')
18 files changed, 601 insertions, 357 deletions
diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc index 48788197..13ed0b64 100644 --- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc @@ -98,7 +98,8 @@ class MockGeneratorContext : public GeneratorContext { &actual_contents, true)); EXPECT_TRUE(actual_contents == *expected_contents) << physical_filename << " needs to be regenerated. Please run " - "generate_descriptor_proto.sh and add this file " + "google/protobuf/compiler/release_compiler.sh and " + "generate_descriptor_proto.sh. Then add this file " "to your CL."; } diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc index 3ce1f120..0404b739 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc @@ -47,7 +47,7 @@ namespace cpp { namespace { // The GOOGLE_ARRAYSIZE constant is the max enum value plus 1. If the max enum value -// is kint32max, GOOGLE_ARRAYSIZE will overflow. In such cases we should omit the +// is ::google::protobuf::kint32max, GOOGLE_ARRAYSIZE will overflow. In such cases we should omit the // generation of the GOOGLE_ARRAYSIZE constant. bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) { int32 max_value = descriptor->value(0)->number(); @@ -56,7 +56,7 @@ bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) { max_value = descriptor->value(i)->number(); } } - return max_value != kint32max; + return max_value != ::google::protobuf::kint32max; } } // namespace @@ -153,9 +153,12 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) { void EnumGenerator:: GenerateGetEnumDescriptorSpecializations(io::Printer* printer) { + printer->Print( + "template <> struct is_proto_enum< $classname$> : ::google::protobuf::internal::true_type " + "{};\n", + "classname", ClassName(descriptor_, true)); if (HasDescriptorMethods(descriptor_->file())) { printer->Print( - "template <> struct is_proto_enum< $classname$> : ::google::protobuf::internal::true_type {};\n" "template <>\n" "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n" " return $classname$_descriptor();\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc index 17926135..74989703 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc @@ -76,23 +76,26 @@ GeneratePrivateMembers(io::Printer* printer) const { void EnumFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "inline $type$ $name$() const$deprecation$;\n" - "inline void set_$name$($type$ value)$deprecation$;\n"); + "$type$ $name$() const$deprecation$;\n" + "void set_$name$($type$ value)$deprecation$;\n"); } void EnumFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $classname$::$name$() const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ $type$ $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return static_cast< $type$ >($name$_);\n" "}\n" - "inline void $classname$::set_$name$($type$ value) {\n"); + "$inline$ void $classname$::set_$name$($type$ value) {\n"); if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) { - printer->Print(variables_, + printer->Print(variables, " assert($type$_IsValid(value));\n"); } - printer->Print(variables_, + printer->Print(variables, " $set_hasbit$\n" " $name$_ = value;\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" @@ -181,21 +184,24 @@ EnumOneofFieldGenerator(const FieldDescriptor* descriptor, EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {} void EnumOneofFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $classname$::$name$() const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ $type$ $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " if (has_$name$()) {\n" " return static_cast< $type$ >($oneof_prefix$$name$_);\n" " }\n" " return static_cast< $type$ >($default$);\n" "}\n" - "inline void $classname$::set_$name$($type$ value) {\n"); + "$inline$ void $classname$::set_$name$($type$ value) {\n"); if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) { - printer->Print(variables_, + printer->Print(variables, " assert($type$_IsValid(value));\n"); } - printer->Print(variables_, + printer->Print(variables, " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -246,46 +252,49 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedEnumFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "inline $type$ $name$(int index) const$deprecation$;\n" - "inline void set_$name$(int index, $type$ value)$deprecation$;\n" - "inline void add_$name$($type$ value)$deprecation$;\n"); + "$type$ $name$(int index) const$deprecation$;\n" + "void set_$name$(int index, $type$ value)$deprecation$;\n" + "void add_$name$($type$ value)$deprecation$;\n"); printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField<int>& $name$() const$deprecation$;\n" - "inline ::google::protobuf::RepeatedField<int>* mutable_$name$()$deprecation$;\n"); + "const ::google::protobuf::RepeatedField<int>& $name$() const$deprecation$;\n" + "::google::protobuf::RepeatedField<int>* mutable_$name$()$deprecation$;\n"); } void RepeatedEnumFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $classname$::$name$(int index) const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ $type$ $classname$::$name$(int index) const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return static_cast< $type$ >($name$_.Get(index));\n" "}\n" - "inline void $classname$::set_$name$(int index, $type$ value) {\n"); + "$inline$ void $classname$::set_$name$(int index, $type$ value) {\n"); if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) { - printer->Print(variables_, + printer->Print(variables, " assert($type$_IsValid(value));\n"); } - printer->Print(variables_, + printer->Print(variables, " $name$_.Set(index, value);\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" - "inline void $classname$::add_$name$($type$ value) {\n"); + "$inline$ void $classname$::add_$name$($type$ value) {\n"); if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) { - printer->Print(variables_, + printer->Print(variables, " assert($type$_IsValid(value));\n"); } - printer->Print(variables_, + printer->Print(variables, " $name$_.Add(value);\n" " // @@protoc_insertion_point(field_add:$full_name$)\n" "}\n"); - printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField<int>&\n" + printer->Print(variables, + "$inline$ const ::google::protobuf::RepeatedField<int>&\n" "$classname$::$name$() const {\n" " // @@protoc_insertion_point(field_list:$full_name$)\n" " return $name$_;\n" "}\n" - "inline ::google::protobuf::RepeatedField<int>*\n" + "$inline$ ::google::protobuf::RepeatedField<int>*\n" "$classname$::mutable_$name$() {\n" " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n" " return &$name$_;\n" @@ -344,20 +353,34 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { void RepeatedEnumFieldGenerator:: GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { if (!descriptor_->options().packed()) { - // We use a non-inlined implementation in this case, since this path will - // rarely be executed. - printer->Print(variables_, - "DO_((::google::protobuf::internal::WireFormatLite::ReadPackedEnumNoInline(\n" - " input,\n"); + // This path is rarely executed, so we use a non-inlined implementation. if (HasPreservingUnknownEnumSemantics(descriptor_->file())) { printer->Print(variables_, - " NULL,\n"); + "DO_((::google::protobuf::internal::" + "WireFormatLite::ReadPackedEnumPreserveUnknowns(\n" + " input,\n" + " $number$,\n" + " NULL,\n" + " NULL,\n" + " this->mutable_$name$())));\n"); + } else if (UseUnknownFieldSet(descriptor_->file())) { + printer->Print(variables_, + "DO_((::google::protobuf::internal::WireFormat::ReadPackedEnumPreserveUnknowns(\n" + " input,\n" + " $number$,\n" + " $type$_IsValid,\n" + " mutable_unknown_fields(),\n" + " this->mutable_$name$())));\n"); } else { printer->Print(variables_, - " &$type$_IsValid,\n"); + "DO_((::google::protobuf::internal::" + "WireFormatLite::ReadPackedEnumPreserveUnknowns(\n" + " input,\n" + " $number$,\n" + " $type$_IsValid,\n" + " &unknown_fields_stream,\n" + " this->mutable_$name$())));\n"); } - printer->Print(variables_, - " this->mutable_$name$())));\n"); } else { printer->Print(variables_, "::google::protobuf::uint32 length;\n" @@ -376,6 +399,16 @@ GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { printer->Print(variables_, " if ($type$_IsValid(value)) {\n" " add_$name$(static_cast< $type$ >(value));\n" + " } else {\n"); + if (UseUnknownFieldSet(descriptor_->file())) { + printer->Print(variables_, + " mutable_unknown_fields()->AddVarint($number$, value);\n"); + } else { + printer->Print(variables_, + " unknown_fields_stream.WriteVarint32(tag);\n" + " unknown_fields_stream.WriteVarint32(value);\n"); + } + printer->Print( " }\n"); } printer->Print(variables_, diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/src/google/protobuf/compiler/cpp/cpp_enum_field.h index def2b232..5b1d01ea 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.h @@ -53,7 +53,8 @@ class EnumFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; @@ -78,7 +79,8 @@ class EnumOneofFieldGenerator : public EnumFieldGenerator { ~EnumOneofFieldGenerator(); // implements FieldGenerator --------------------------------------- - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; void GenerateConstructorCode(io::Printer* printer) const; @@ -96,7 +98,8 @@ class RepeatedEnumFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h index c37fe0be..cd2b6b75 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_field.h @@ -89,7 +89,7 @@ class FieldGenerator { // Generate inline definitions of accessor functions for this field. // These are placed inside the header after all class definitions. virtual void GenerateInlineAccessorDefinitions( - io::Printer* printer) const = 0; + io::Printer* printer, bool is_inline) const = 0; // Generate definitions of accessors that aren't inlined. These are // placed somewhere in the .cc file. diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index fae4df40..a98c7d92 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -136,8 +136,11 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { printer->Print( "#include <google/protobuf/arena.h>\n" "#include <google/protobuf/arenastring.h>\n" - "#include <google/protobuf/generated_message_util.h>\n" - "#include <google/protobuf/metadata.h>\n"); + "#include <google/protobuf/generated_message_util.h>\n"); + if (UseUnknownFieldSet(file_)) { + printer->Print( + "#include <google/protobuf/metadata.h>\n"); + } if (file_->message_type_count() > 0) { if (HasDescriptorMethods(file_)) { printer->Print( @@ -152,13 +155,24 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { "#include <google/protobuf/extension_set.h>\n"); if (HasMapFields(file_)) { printer->Print( - "#include <google/protobuf/map.h>\n" - "#include <google/protobuf/map_field_inl.h>\n"); + "#include <google/protobuf/map.h>\n"); + if (HasDescriptorMethods(file_)) { + printer->Print( + "#include <google/protobuf/map_field_inl.h>\n"); + } else { + printer->Print( + "#include <google/protobuf/map_field_lite.h>\n"); + } } - if (HasDescriptorMethods(file_) && HasEnumDefinitions(file_)) { - printer->Print( - "#include <google/protobuf/generated_enum_reflection.h>\n"); + if (HasEnumDefinitions(file_)) { + if (HasDescriptorMethods(file_)) { + printer->Print( + "#include <google/protobuf/generated_enum_reflection.h>\n"); + } else { + printer->Print( + "#include <google/protobuf/generated_enum_util.h>\n"); + } } if (HasGenericServices(file_)) { @@ -272,15 +286,17 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { printer->Print(kThickSeparator); printer->Print("\n"); - + printer->Print("#if !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); // Generate class inline methods. for (int i = 0; i < file_->message_type_count(); i++) { if (i > 0) { printer->Print(kThinSeparator); printer->Print("\n"); } - message_generators_[i]->GenerateInlineMethods(printer); + message_generators_[i]->GenerateInlineMethods(printer, + /* is_inline = */ true); } + printer->Print("#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); printer->Print( "\n" @@ -290,7 +306,7 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { GenerateNamespaceClosers(printer); // Emit GetEnumDescriptor specializations into google::protobuf namespace: - if (HasDescriptorMethods(file_)) { + if (HasEnumDefinitions(file_)) { // The SWIG conditional is to avoid a null-pointer dereference // (bug 1984964) in swig-1.3.21 resulting from the following syntax: // namespace X { void Y<Z::W>(); } @@ -417,6 +433,12 @@ void FileGenerator::GenerateSource(io::Printer* printer) { printer->Print(kThickSeparator); printer->Print("\n"); message_generators_[i]->GenerateClassMethods(printer); + + printer->Print("#if PROTOBUF_INLINE_NOT_IN_HEADERS\n"); + // Generate class inline methods. + message_generators_[i]->GenerateInlineMethods(printer, + /* is_inline = */ false); + printer->Print("#endif // PROTOBUF_INLINE_NOT_IN_HEADERS\n"); } if (HasGenericServices(file_)) { diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 28c4dd54..237278db 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -352,9 +352,7 @@ string FilenameIdentifier(const string& filename) { } else { // Not alphanumeric. To avoid any possibility of name conflicts we // use the hex code for the character. - result.push_back('_'); - char buffer[kFastToBufferSize]; - result.append(FastHexToBuffer(static_cast<uint8>(filename[i]), buffer)); + StrAppend(&result, "_", ToHex(static_cast<uint8>(filename[i]))); } } return result; @@ -508,6 +506,13 @@ bool IsStringOrMessage(const FieldDescriptor* field) { return false; } +FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field) { + GOOGLE_DCHECK(field->cpp_type() == FieldDescriptor::CPPTYPE_STRING); + // Open-source protobuf release only supports STRING ctype. + return FieldOptions::STRING; + +} + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index e60fa7c2..c7bb8f98 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -211,6 +211,10 @@ inline bool IsMapEntryMessage(const Descriptor* descriptor) { // Returns true if the field's CPPTYPE is string or message. bool IsStringOrMessage(const FieldDescriptor* field); +// For a string field, returns the effective ctype. If the actual ctype is +// not supported, returns the default of STRING. +FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field); + string UnderscoresToCamelCase(const string& input, bool cap_next_letter); inline bool HasFieldPresence(const FileDescriptor* file) { diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc index 0154eeb8..8c38db2b 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc @@ -31,6 +31,7 @@ #include <google/protobuf/compiler/cpp/cpp_map_field.h> #include <google/protobuf/compiler/cpp/cpp_helpers.h> #include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> #include <google/protobuf/stubs/strutil.h> namespace google { @@ -72,14 +73,21 @@ void SetMessageVariables(const FieldDescriptor* descriptor, (*variables)["val_cpp"] = PrimitiveTypeName(val->cpp_type()); (*variables)["wrapper"] = "EntryWrapper"; } - (*variables)["key_type"] = - "::google::protobuf::FieldDescriptor::TYPE_" + + (*variables)["key_wire_type"] = + "::google::protobuf::internal::WireFormatLite::TYPE_" + ToUpper(DeclaredTypeMethodName(key->type())); - (*variables)["val_type"] = - "::google::protobuf::FieldDescriptor::TYPE_" + + (*variables)["val_wire_type"] = + "::google::protobuf::internal::WireFormatLite::TYPE_" + ToUpper(DeclaredTypeMethodName(val->type())); (*variables)["map_classname"] = ClassName(descriptor->message_type(), false); - (*variables)["number"] = Int32ToString(descriptor->number()); + (*variables)["number"] = SimpleItoa(descriptor->number()); + (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor)); + + if (HasDescriptorMethods(descriptor->file())) { + (*variables)["lite"] = ""; + } else { + (*variables)["lite"] = "Lite"; + } if (!IsProto3Field(descriptor) && val->type() == FieldDescriptor::TYPE_ENUM) { @@ -102,33 +110,40 @@ MapFieldGenerator::~MapFieldGenerator() {} void MapFieldGenerator:: GeneratePrivateMembers(io::Printer* printer) const { printer->Print(variables_, - "typedef ::google::protobuf::internal::MapEntry<\n" + "typedef ::google::protobuf::internal::MapEntryLite<\n" " $key_cpp$, $val_cpp$,\n" - " $key_type$,\n" - " $val_type$, $default_enum_value$>\n" + " $key_wire_type$,\n" + " $val_wire_type$,\n" + " $default_enum_value$ >\n" " $map_classname$;\n" - "::google::protobuf::internal::MapField< $key_cpp$, $val_cpp$," - "$key_type$, $val_type$, $default_enum_value$ > $name$_;\n"); + "::google::protobuf::internal::MapField$lite$<\n" + " $key_cpp$, $val_cpp$,\n" + " $key_wire_type$,\n" + " $val_wire_type$,\n" + " $default_enum_value$ > $name$_;\n"); } void MapFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "inline const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" + "const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" " $name$() const$deprecation$;\n" - "inline ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" + "::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" " mutable_$name$()$deprecation$;\n"); } void MapFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ const ::google::protobuf::Map< $key_cpp$, $val_cpp$ >&\n" "$classname$::$name$() const {\n" " // @@protoc_insertion_point(field_map:$full_name$)\n" " return $name$_.GetMap();\n" "}\n" - "inline ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" + "$inline$ ::google::protobuf::Map< $key_cpp$, $val_cpp$ >*\n" "$classname$::mutable_$name$() {\n" " // @@protoc_insertion_point(field_mutable_map:$full_name$)\n" " return $name$_.MutableMap();\n" @@ -198,11 +213,29 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { " if ($val_cpp$_IsValid(*entry->mutable_value())) {\n" " (*mutable_$name$())[entry->key()] =\n" " static_cast<$val_cpp$>(*entry->mutable_value());\n" - " } else {\n" - " mutable_unknown_fields()->AddLengthDelimited($number$, data);\n" + " } else {\n"); + if (HasDescriptorMethods(descriptor_->file())) { + printer->Print(variables_, + " mutable_unknown_fields()" + "->AddLengthDelimited($number$, data);\n"); + } else { + printer->Print(variables_, + " unknown_fields_stream.WriteVarint32($tag$);\n" + " unknown_fields_stream.WriteVarint32(data.size());\n" + " unknown_fields_stream.WriteString(data);\n"); + } + + + printer->Print(variables_, " }\n" "}\n"); } + + // If entry is allocated by arena, its desctructor should be avoided. + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + "if (entry->GetArena() != NULL) entry.release();\n"); + } } void MapFieldGenerator:: @@ -211,12 +244,31 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const { "{\n" " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" - " it = $name$().begin(); it != $name$().end(); ++it) {\n" + " it = $name$().begin(); it != $name$().end(); ++it) {\n"); + + // If entry is allocated by arena, its desctructor should be avoided. + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" + " entry.release();\n" + " }\n"); + } + + printer->Print(variables_, " entry.reset($name$_.New$wrapper$(it->first, it->second));\n" " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n" " $number$, *entry, output);\n" - " }\n" - "}\n"); + " }\n"); + + // If entry is allocated by arena, its desctructor should be avoided. + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" + " entry.release();\n" + " }\n"); + } + + printer->Print("}\n"); } void MapFieldGenerator:: @@ -225,13 +277,32 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { "{\n" " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" - " it = $name$().begin(); it != $name$().end(); ++it) {\n" + " it = $name$().begin(); it != $name$().end(); ++it) {\n"); + + // If entry is allocated by arena, its desctructor should be avoided. + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" + " entry.release();\n" + " }\n"); + } + + printer->Print(variables_, " entry.reset($name$_.New$wrapper$(it->first, it->second));\n" " target = ::google::protobuf::internal::WireFormatLite::\n" " Write$declared_type$NoVirtualToArray(\n" " $number$, *entry, target);\n" - " }\n" - "}\n"); + " }\n"); + + // If entry is allocated by arena, its desctructor should be avoided. + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" + " entry.release();\n" + " }\n"); + } + + printer->Print("}\n"); } void MapFieldGenerator:: @@ -241,12 +312,31 @@ GenerateByteSize(io::Printer* printer) const { "{\n" " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" - " it = $name$().begin(); it != $name$().end(); ++it) {\n" + " it = $name$().begin(); it != $name$().end(); ++it) {\n"); + + // If entry is allocated by arena, its desctructor should be avoided. + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" + " entry.release();\n" + " }\n"); + } + + printer->Print(variables_, " entry.reset($name$_.New$wrapper$(it->first, it->second));\n" " total_size += ::google::protobuf::internal::WireFormatLite::\n" " $declared_type$SizeNoVirtual(*entry);\n" - " }\n" - "}\n"); + " }\n"); + + // If entry is allocated by arena, its desctructor should be avoided. + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + " if (entry.get() != NULL && entry->GetArena() != NULL) {\n" + " entry.release();\n" + " }\n"); + } + + printer->Print("}\n"); } } // namespace cpp diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.h b/src/google/protobuf/compiler/cpp/cpp_map_field.h index 0ff032fd..d27d4851 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.h @@ -50,7 +50,8 @@ class MapFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index d0fd6c6d..bafa36f5 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -87,8 +87,8 @@ const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { for (int i = 0; i < descriptor->field_count(); i++) { fields[i] = descriptor->field(i); } - sort(fields, fields + descriptor->field_count(), - FieldOrderingByNumber()); + std::sort(fields, fields + descriptor->field_count(), + FieldOrderingByNumber()); return fields; } @@ -253,7 +253,7 @@ void OptimizePadding(vector<const FieldDescriptor*>* fields) { // Sort by preferred location to keep fields as close to their original // location as possible. Using stable_sort ensures that the output is // consistent across runs. - stable_sort(aligned_to_4.begin(), aligned_to_4.end()); + std::stable_sort(aligned_to_4.begin(), aligned_to_4.end()); // Now group fields aligned to 4 bytes (or the 4-field groups created above) // into pairs, and treat those like a single field aligned to 8 bytes. @@ -269,7 +269,7 @@ void OptimizePadding(vector<const FieldDescriptor*>* fields) { aligned_to_8.push_back(field_group); } // Sort by preferred location. - stable_sort(aligned_to_8.begin(), aligned_to_8.end()); + std::stable_sort(aligned_to_8.begin(), aligned_to_8.end()); // Now pull out all the FieldDescriptors in order. fields->clear(); @@ -347,11 +347,11 @@ void CollectMapInfo(const Descriptor* descriptor, default: (*variables)["val"] = PrimitiveTypeName(val->cpp_type()); } - (*variables)["key_type"] = - "::google::protobuf::FieldDescriptor::TYPE_" + + (*variables)["key_wire_type"] = + "::google::protobuf::internal::WireFormatLite::TYPE_" + ToUpper(DeclaredTypeMethodName(key->type())); - (*variables)["val_type"] = - "::google::protobuf::FieldDescriptor::TYPE_" + + (*variables)["val_wire_type"] = + "::google::protobuf::internal::WireFormatLite::TYPE_" + ToUpper(DeclaredTypeMethodName(val->type())); } @@ -453,17 +453,17 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { vars["constant_name"] = FieldConstantName(field); if (field->is_repeated()) { - printer->Print(vars, "inline int $name$_size() const$deprecation$;\n"); + printer->Print(vars, "int $name$_size() const$deprecation$;\n"); } else if (HasHasMethod(field)) { - printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n"); + printer->Print(vars, "bool has_$name$() const$deprecation$;\n"); } else if (HasPrivateHasMethod(field)) { printer->Print(vars, "private:\n" - "inline bool has_$name$() const$deprecation$;\n" + "bool has_$name$() const$deprecation$;\n" "public:\n"); } - printer->Print(vars, "inline void clear_$name$()$deprecation$;\n"); + printer->Print(vars, "void clear_$name$()$deprecation$;\n"); printer->Print(vars, "static const int $constant_name$ = $number$;\n"); // Generate type-specific accessor declarations. @@ -482,7 +482,7 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { printer->Print( - "inline $camel_oneof_name$Case $oneof_name$_case() const;\n", + "$camel_oneof_name$Case $oneof_name$_case() const;\n", "camel_oneof_name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true), "oneof_name", descriptor_->oneof_decl(i)->name()); @@ -490,7 +490,7 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { } void MessageGenerator:: -GenerateFieldAccessorDefinitions(io::Printer* printer) { +GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) { printer->Print("// $classname$\n\n", "classname", classname_); for (int i = 0; i < descriptor_->field_count(); i++) { @@ -500,11 +500,12 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { map<string, string> vars; SetCommonFieldVariables(field, &vars, options_); + vars["inline"] = is_inline ? "inline" : ""; // Generate has_$name$() or $name$_size(). if (field->is_repeated()) { printer->Print(vars, - "inline int $classname$::$name$_size() const {\n" + "$inline$ int $classname$::$name$_size() const {\n" " return $name$_.size();\n" "}\n"); } else if (field->containing_oneof()) { @@ -518,11 +519,11 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { vars["oneof_name"] = field->containing_oneof()->name(); vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index()); printer->Print(vars, - "inline bool $classname$::has_$name$() const {\n" + "$inline$ bool $classname$::has_$name$() const {\n" " return $oneof_name$_case() == k$field_name$;\n" "}\n"); printer->Print(vars, - "inline void $classname$::set_has_$name$() {\n" + "$inline$ void $classname$::set_has_$name$() {\n" " _oneof_case_[$oneof_index$] = k$field_name$;\n" "}\n"); } else { @@ -535,13 +536,13 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), buffer); printer->Print(vars, - "inline bool $classname$::has_$name$() const {\n" + "$inline$ bool $classname$::has_$name$() const {\n" " return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n" "}\n" - "inline void $classname$::set_has_$name$() {\n" + "$inline$ void $classname$::set_has_$name$() {\n" " _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n" "}\n" - "inline void $classname$::clear_has_$name$() {\n" + "$inline$ void $classname$::clear_has_$name$() {\n" " _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n" "}\n" ); @@ -551,12 +552,12 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { bool is_lazy = false; if (is_lazy) { printer->Print(vars, - "inline bool $classname$::has_$name$() const {\n" + "$inline$ bool $classname$::has_$name$() const {\n" " return !$name$_.IsCleared();\n" "}\n"); } else { printer->Print(vars, - "inline bool $classname$::has_$name$() const {\n" + "$inline$ bool $classname$::has_$name$() const {\n" " return !_is_default_instance_ && $name$_ != NULL;\n" "}\n"); } @@ -566,7 +567,7 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { // Generate clear_$name$() printer->Print(vars, - "inline void $classname$::clear_$name$() {\n"); + "$inline$ void $classname$::clear_$name$() {\n"); printer->Indent(); @@ -595,7 +596,8 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { printer->Print("}\n"); // Generate type-specific accessors. - field_generators_.get(field).GenerateInlineAccessorDefinitions(printer); + field_generators_.get(field).GenerateInlineAccessorDefinitions(printer, + is_inline); printer->Print("\n"); } @@ -608,12 +610,13 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { vars["cap_oneof_name"] = ToUpper(descriptor_->oneof_decl(i)->name()); vars["classname"] = classname_; + vars["inline"] = is_inline ? "inline" : ""; printer->Print( vars, - "inline bool $classname$::has_$oneof_name$() const {\n" + "$inline$ bool $classname$::has_$oneof_name$() const {\n" " return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n" "}\n" - "inline void $classname$::clear_has_$oneof_name$() {\n" + "$inline$ void $classname$::clear_has_$oneof_name$() {\n" " _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n" "}\n"); } @@ -1169,18 +1172,18 @@ GenerateClassDefinition(io::Printer* printer) { } void MessageGenerator:: -GenerateInlineMethods(io::Printer* printer) { +GenerateInlineMethods(io::Printer* printer, bool is_inline) { for (int i = 0; i < descriptor_->nested_type_count(); i++) { // map entry message doesn't need inline methods. Since map entry message // cannot be a top level class, we just need to avoid calling // GenerateInlineMethods here. if (IsMapEntryMessage(descriptor_->nested_type(i))) continue; - nested_generators_[i]->GenerateInlineMethods(printer); + nested_generators_[i]->GenerateInlineMethods(printer, is_inline); printer->Print(kThinSeparator); printer->Print("\n"); } - GenerateFieldAccessorDefinitions(printer); + GenerateFieldAccessorDefinitions(printer, is_inline); // Generate oneof_case() functions. for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { @@ -1190,9 +1193,10 @@ GenerateInlineMethods(io::Printer* printer) { descriptor_->oneof_decl(i)->name(), true); vars["oneof_name"] = descriptor_->oneof_decl(i)->name(); vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index()); + vars["inline"] = is_inline ? "inline " : ""; printer->Print( vars, - "inline $class_name$::$camel_oneof_name$Case $class_name$::" + "$inline$$class_name$::$camel_oneof_name$Case $class_name$::" "$oneof_name$_case() const {\n" " return $class_name$::$camel_oneof_name$Case(" "_oneof_case_[$oneof_index$]);\n" @@ -1222,7 +1226,9 @@ GenerateDescriptorDeclarations(io::Printer* printer) { for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); printer->Print(" "); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || + (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING && + EffectiveStringCType(field) != FieldOptions::STRING)) { printer->Print("const "); } field_generators_.get(field).GeneratePrivateMembers(printer); @@ -1391,8 +1397,8 @@ GenerateTypeRegistrations(io::Printer* printer) { " ::google::protobuf::internal::MapEntry<\n" " $key$,\n" " $val$,\n" - " $key_type$,\n" - " $val_type$,\n" + " $key_wire_type$,\n" + " $val_wire_type$,\n" " $default_enum_value$>::CreateDefaultInstance(\n" " $classname$_descriptor_));\n"); } @@ -2034,17 +2040,16 @@ GenerateClear(io::Printer* printer) { // Step 2a: Greedily seek runs of fields that can be cleared by memset-to-0. // The generated code uses two macros to help it clear runs of fields: - // OFFSET_OF_FIELD_ computes the offset (in bytes) of a field in the Message. + // ZR_HELPER_(f1) - ZR_HELPER_(f0) computes the difference, in bytes, of the + // positions of two fields in the Message. // ZR_ zeroes a non-empty range of fields via memset. const char* macros = - "#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \\\n" - " &reinterpret_cast<$classname$*>(16)->f) - \\\n" - " reinterpret_cast<char*>(16))\n\n" - "#define ZR_(first, last) do { \\\n" - " size_t f = OFFSET_OF_FIELD_(first); \\\n" - " size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \\\n" - " ::memset(&first, 0, n); \\\n" - " } while (0)\n\n"; + "#define ZR_HELPER_(f) reinterpret_cast<char*>(\\\n" + " &reinterpret_cast<$classname$*>(16)->f)\n\n" + "#define ZR_(first, last) do {\\\n" + " ::memset(&first, 0,\\\n" + " ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\\\n" + "} while (0)\n\n"; for (int i = 0; i < runs_of_fields_.size(); i++) { const vector<string>& run = runs_of_fields_[i]; if (run.size() < 2) continue; @@ -2133,7 +2138,7 @@ GenerateClear(io::Printer* printer) { } if (macros_are_needed) { printer->Outdent(); - printer->Print("\n#undef OFFSET_OF_FIELD_\n#undef ZR_\n\n"); + printer->Print("\n#undef ZR_HELPER_\n#undef ZR_\n\n"); printer->Indent(); } @@ -2919,8 +2924,8 @@ GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { for (int i = 0; i < descriptor_->extension_range_count(); ++i) { sorted_extensions.push_back(descriptor_->extension_range(i)); } - sort(sorted_extensions.begin(), sorted_extensions.end(), - ExtensionRangeSorter()); + std::sort(sorted_extensions.begin(), sorted_extensions.end(), + ExtensionRangeSorter()); // Merge the fields and the extension ranges, both sorted by field number. int i, j; diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index dfbc9af5..ea96581d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/src/google/protobuf/compiler/cpp/cpp_message.h @@ -82,7 +82,7 @@ class MessageGenerator { // Generate definitions of inline methods (placed at the end of the header // file). - void GenerateInlineMethods(io::Printer* printer); + void GenerateInlineMethods(io::Printer* printer, bool is_inline); // Source file stuff. @@ -116,7 +116,7 @@ class MessageGenerator { private: // Generate declarations and definitions of accessors for fields. void GenerateFieldAccessorDeclarations(io::Printer* printer); - void GenerateFieldAccessorDefinitions(io::Printer* printer); + void GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline); // Generate the field offsets array. void GenerateOffsets(io::Printer* printer); diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc index b3cd0ba1..467b6bf6 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -85,76 +85,141 @@ GeneratePrivateMembers(io::Printer* printer) const { void MessageFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + "private:\n" + "void _slow_mutable_$name$()$deprecation$;\n"); + if (SupportsArenas(descriptor_->message_type())) { + printer->Print(variables_, + "void _slow_set_allocated_$name$(\n" + " ::google::protobuf::Arena* message_arena, $type$** $name$)$deprecation$;\n"); + } + printer->Print(variables_, + "$type$* _slow_$release_name$()$deprecation$;\n" + "public:\n"); + } printer->Print(variables_, - "inline const $type$& $name$() const$deprecation$;\n" - "inline $type$* mutable_$name$()$deprecation$;\n" - "inline $type$* $release_name$()$deprecation$;\n" - "inline void set_allocated_$name$($type$* $name$)$deprecation$;\n"); + "const $type$& $name$() const$deprecation$;\n" + "$type$* mutable_$name$()$deprecation$;\n" + "$type$* $release_name$()$deprecation$;\n" + "void set_allocated_$name$($type$* $name$)$deprecation$;\n"); if (SupportsArenas(descriptor_)) { printer->Print(variables_, - "inline $type$* unsafe_arena_release_$name$()$deprecation$;\n" - "inline void unsafe_arena_set_allocated_$name$(\n" + "$type$* unsafe_arena_release_$name$()$deprecation$;\n" + "void unsafe_arena_set_allocated_$name$(\n" " $type$* $name$)$deprecation$;\n"); } } +void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions( + io::Printer* printer) const { + if (SupportsArenas(descriptor_)) { + printer->Print(variables_, + "void $classname$::_slow_mutable_$name$() {\n"); + if (SupportsArenas(descriptor_->message_type())) { + printer->Print(variables_, + " $name$_ = ::google::protobuf::Arena::CreateMessage< $type$ >(\n" + " GetArenaNoVirtual());\n"); + } else { + printer->Print(variables_, + " $name$_ = ::google::protobuf::Arena::Create< $type$ >(\n" + " GetArenaNoVirtual());\n"); + } + printer->Print(variables_, + "}\n" + "$type$* $classname$::_slow_$release_name$() {\n" + " if ($name$_ == NULL) {\n" + " return NULL;\n" + " } else {\n" + " $type$* temp = new $type$;\n" + " temp->MergeFrom(*$name$_);\n" + " $name$_ = NULL;\n" + " return temp;\n" + " }\n" + "}\n" + "$type$* $classname$::unsafe_arena_release_$name$() {\n" + " $clear_hasbit$\n" + " $type$* temp = $name$_;\n" + " $name$_ = NULL;\n" + " return temp;\n" + "}\n"); + if (SupportsArenas(descriptor_->message_type())) { + printer->Print(variables_, + "void $classname$::_slow_set_allocated_$name$(\n" + " ::google::protobuf::Arena* message_arena, $type$** $name$) {\n" + " if (message_arena != NULL && \n" + " ::google::protobuf::Arena::GetArena(*$name$) == NULL) {\n" + " message_arena->Own(*$name$);\n" + " } else if (message_arena !=\n" + " ::google::protobuf::Arena::GetArena(*$name$)) {\n" + " $type$* new_$name$ = \n" + " ::google::protobuf::Arena::CreateMessage< $type$ >(\n" + " message_arena);\n" + " new_$name$->CopyFrom(**$name$);\n" + " *$name$ = new_$name$;\n" + " }\n" + "}\n"); + } + printer->Print(variables_, + "void $classname$::unsafe_arena_set_allocated_$name$(\n" + " $type$* $name$) {\n" + // If we're not on an arena, free whatever we were holding before. + // (If we are on arena, we can just forget the earlier pointer.) + " if (GetArenaNoVirtual() == NULL) {\n" + " delete $name$_;\n" + " }\n" + " $name$_ = $name$;\n" + " if ($name$) {\n" + " $set_hasbit$\n" + " } else {\n" + " $clear_hasbit$\n" + " }\n" + " // @@protoc_insertion_point(field_unsafe_arena_set_allocated" + ":$full_name$)\n" + "}\n"); + } +} + void MessageFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const $type$& $classname$::$name$() const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ const $type$& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n"); PrintHandlingOptionalStaticInitializers( - variables_, descriptor_->file(), printer, + variables, descriptor_->file(), printer, // With static initializers. " return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n", // Without. " return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n"); if (SupportsArenas(descriptor_)) { - printer->Print(variables_, + printer->Print(variables, "}\n" - "inline $type$* $classname$::mutable_$name$() {\n" + "$inline$ $type$* $classname$::mutable_$name$() {\n" " $set_hasbit$\n" - " if ($name$_ == NULL) {\n"); - if (SupportsArenas(descriptor_->message_type())) { - printer->Print(variables_, - " $name$_ = ::google::protobuf::Arena::CreateMessage< $type$ >(\n" - " GetArenaNoVirtual());\n"); - } else { - printer->Print(variables_, - " $name$_ = ::google::protobuf::Arena::Create< $type$ >(\n" - " GetArenaNoVirtual());\n"); - } - printer->Print(variables_, " }\n" + " if ($name$_ == NULL) {\n" + " _slow_mutable_$name$();" + " }\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $name$_;\n" "}\n" - "inline $type$* $classname$::$release_name$() {\n" + "$inline$ $type$* $classname$::$release_name$() {\n" " $clear_hasbit$\n" " if (GetArenaNoVirtual() != NULL) {\n" - " if ($name$_ == NULL) {\n" - " return NULL;\n" - " } else {\n" - " $type$* temp = new $type$;\n" - " temp->MergeFrom(*$name$_);\n" - " $name$_ = NULL;\n" - " return temp;\n" - " }\n" + " return _slow_$release_name$();\n" " } else {\n" " $type$* temp = $name$_;\n" " $name$_ = NULL;\n" " return temp;\n" " }\n" "}\n" - "inline $type$* $classname$::unsafe_arena_release_$name$() {\n" - " $clear_hasbit$\n" - " $type$* temp = $name$_;\n" - " $name$_ = NULL;\n" - " return temp;\n" - "}\n" - "inline void $classname$::set_allocated_$name$($type$* $name$) {\n" - " if (GetArenaNoVirtual() == NULL) {\n" + "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n" + " ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();\n" + " if (message_arena == NULL) {\n" " delete $name$_;\n" " }\n" " if ($name$ != NULL) {\n"); @@ -164,26 +229,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { // so we might as well defer it. Otherwise, if incoming message is on a // different ownership domain (specific arena, or the heap) than we are, // copy to our arena (or heap, as the case may be). - printer->Print(variables_, - " if (GetArenaNoVirtual() != NULL && \n" - " ::google::protobuf::Arena::GetArena($name$) == NULL) {\n" - " GetArenaNoVirtual()->Own($name$);\n" - " } else if (GetArenaNoVirtual() !=\n" - " ::google::protobuf::Arena::GetArena($name$)) {\n" - " $type$* new_$name$ = \n" - " ::google::protobuf::Arena::CreateMessage< $type$ >(\n" - " GetArenaNoVirtual());\n" - " new_$name$->CopyFrom(*$name$);\n" - " $name$ = new_$name$;\n" - " }\n"); + printer->Print(variables, + " _slow_set_allocated_$name$(message_arena, &$name$);\n"); } else { - printer->Print(variables_, - " if (GetArenaNoVirtual() != NULL) {\n" - " GetArenaNoVirtual()->Own($name$);\n" + printer->Print(variables, + " if (message_arena != NULL) {\n" + " message_arena->Own($name$);\n" " }\n"); } - - printer->Print(variables_, + printer->Print(variables, " }\n" " $name$_ = $name$;\n" " if ($name$) {\n" @@ -192,27 +246,11 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " $clear_hasbit$\n" " }\n" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" - "}\n" - "inline void $classname$::unsafe_arena_set_allocated_$name$(\n" - " $type$* $name$) {\n" - // If we're not on an arena, free whatever we were holding before. - // (If we are on arena, we can just forget the earlier pointer.) - " if (GetArenaNoVirtual() == NULL) {\n" - " delete $name$_;\n" - " }\n" - " $name$_ = $name$;\n" - " if ($name$) {\n" - " $set_hasbit$\n" - " } else {\n" - " $clear_hasbit$\n" - " }\n" - " // @@protoc_insertion_point(field_unsafe_arena_set_allocated" - ":$full_name$)\n" "}\n"); } else { - printer->Print(variables_, + printer->Print(variables, "}\n" - "inline $type$* $classname$::mutable_$name$() {\n" + "$inline$ $type$* $classname$::mutable_$name$() {\n" " $set_hasbit$\n" " if ($name$_ == NULL) {\n" " $name$_ = new $type$;\n" @@ -220,17 +258,17 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $name$_;\n" "}\n" - "inline $type$* $classname$::$release_name$() {\n" + "$inline$ $type$* $classname$::$release_name$() {\n" " $clear_hasbit$\n" " $type$* temp = $name$_;\n" " $name$_ = NULL;\n" " return temp;\n" "}\n" - "inline void $classname$::set_allocated_$name$($type$* $name$) {\n" + "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n" " delete $name$_;\n"); if (SupportsArenas(descriptor_->message_type())) { - printer->Print(variables_, + printer->Print(variables, " if ($name$ != NULL && $name$->GetArena() != NULL) {\n" " $type$* new_$name$ = new $type$;\n" " new_$name$->CopyFrom(*$name$);\n" @@ -238,7 +276,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " }\n"); } - printer->Print(variables_, + printer->Print(variables, " $name$_ = $name$;\n" " if ($name$) {\n" " $set_hasbit$\n" @@ -328,35 +366,38 @@ MessageOneofFieldGenerator(const FieldDescriptor* descriptor, MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {} void MessageOneofFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; if (SupportsArenas(descriptor_)) { - printer->Print(variables_, - "inline const $type$& $classname$::$name$() const {\n" + printer->Print(variables, + "$inline$ const $type$& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return has_$name$() ? *$oneof_prefix$$name$_\n" " : $type$::default_instance();\n" "}\n" - "inline $type$* $classname$::mutable_$name$() {\n" + "$inline$ $type$* $classname$::mutable_$name$() {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n"); if (SupportsArenas(descriptor_->message_type())) { - printer->Print(variables_, + printer->Print(variables, " $oneof_prefix$$name$_ = \n" " ::google::protobuf::Arena::CreateMessage< $type$ >(\n" " GetArenaNoVirtual());\n"); } else { - printer->Print(variables_, + printer->Print(variables, " $oneof_prefix$$name$_ = \n" " ::google::protobuf::Arena::Create< $type$ >(\n" " GetArenaNoVirtual());\n"); } - printer->Print(variables_, + printer->Print(variables, " }\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $oneof_prefix$$name$_;\n" "}\n" - "inline $type$* $classname$::$release_name$() {\n" + "$inline$ $type$* $classname$::$release_name$() {\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" " if (GetArenaNoVirtual() != NULL) {\n" @@ -375,7 +416,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return NULL;\n" " }\n" "}\n" - "inline $type$* $classname$::unsafe_arena_release_$name$() {\n" + "$inline$ $type$* $classname$::unsafe_arena_release_$name$() {\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" " $type$* temp = $oneof_prefix$$name$_;\n" @@ -385,12 +426,12 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return NULL;\n" " }\n" "}\n" - "inline void $classname$::set_allocated_$name$($type$* $name$) {\n" + "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n" " clear_$oneof_name$();\n" " if ($name$) {\n"); if (SupportsArenas(descriptor_->message_type())) { - printer->Print(variables_, + printer->Print(variables, // If incoming message is on the heap and we are on an arena, just Own() // it (see above). If it's on a different arena than we are or one of us // is on the heap, we make a copy to our arena/heap. @@ -406,19 +447,19 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " $name$ = new_$name$;\n" " }\n"); } else { - printer->Print(variables_, + printer->Print(variables, " if (GetArenaNoVirtual() != NULL) {\n" " GetArenaNoVirtual()->Own($name$);\n" " }\n"); } - printer->Print(variables_, + printer->Print(variables, " set_has_$name$();\n" " $oneof_prefix$$name$_ = $name$;\n" " }\n" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" "}\n" - "inline void $classname$::unsafe_arena_set_allocated_$name$(" + "$inline$ void $classname$::unsafe_arena_set_allocated_$name$(" "$type$* $name$) {\n" // We rely on the oneof clear method to free the earlier contents of this // oneof. We can directly use the pointer we're given to set the new @@ -432,13 +473,13 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { "$full_name$)\n" "}\n"); } else { - printer->Print(variables_, - "inline const $type$& $classname$::$name$() const {\n" + printer->Print(variables, + "$inline$ const $type$& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return has_$name$() ? *$oneof_prefix$$name$_\n" " : $type$::default_instance();\n" "}\n" - "inline $type$* $classname$::mutable_$name$() {\n" + "$inline$ $type$* $classname$::mutable_$name$() {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -447,7 +488,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $oneof_prefix$$name$_;\n" "}\n" - "inline $type$* $classname$::$release_name$() {\n" + "$inline$ $type$* $classname$::$release_name$() {\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" " $type$* temp = $oneof_prefix$$name$_;\n" @@ -457,18 +498,18 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return NULL;\n" " }\n" "}\n" - "inline void $classname$::set_allocated_$name$($type$* $name$) {\n" + "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n" " clear_$oneof_name$();\n" " if ($name$) {\n"); if (SupportsArenas(descriptor_->message_type())) { - printer->Print(variables_, + printer->Print(variables, " if ($name$->GetArena() != NULL) {\n" " $type$* new_$name$ = new $type$;\n" " new_$name$->CopyFrom(*$name$);\n" " $name$ = new_$name$;\n" " }\n"); } - printer->Print(variables_, + printer->Print(variables, " set_has_$name$();\n" " $oneof_prefix$$name$_ = $name$;\n" " }\n" @@ -521,38 +562,41 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedMessageFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "inline const $type$& $name$(int index) const$deprecation$;\n" - "inline $type$* mutable_$name$(int index)$deprecation$;\n" - "inline $type$* add_$name$()$deprecation$;\n"); + "const $type$& $name$(int index) const$deprecation$;\n" + "$type$* mutable_$name$(int index)$deprecation$;\n" + "$type$* add_$name$()$deprecation$;\n"); printer->Print(variables_, - "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n" + "const ::google::protobuf::RepeatedPtrField< $type$ >&\n" " $name$() const$deprecation$;\n" - "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n" + "::google::protobuf::RepeatedPtrField< $type$ >*\n" " mutable_$name$()$deprecation$;\n"); } void RepeatedMessageFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const $type$& $classname$::$name$(int index) const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ const $type$& $classname$::$name$(int index) const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return $name$_.$cppget$(index);\n" "}\n" - "inline $type$* $classname$::mutable_$name$(int index) {\n" + "$inline$ $type$* $classname$::mutable_$name$(int index) {\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $name$_.Mutable(index);\n" "}\n" - "inline $type$* $classname$::add_$name$() {\n" + "$inline$ $type$* $classname$::add_$name$() {\n" " // @@protoc_insertion_point(field_add:$full_name$)\n" " return $name$_.Add();\n" "}\n"); - printer->Print(variables_, - "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n" + printer->Print(variables, + "$inline$ const ::google::protobuf::RepeatedPtrField< $type$ >&\n" "$classname$::$name$() const {\n" " // @@protoc_insertion_point(field_list:$full_name$)\n" " return $name$_;\n" "}\n" - "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n" + "$inline$ ::google::protobuf::RepeatedPtrField< $type$ >*\n" "$classname$::mutable_$name$() {\n" " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n" " return &$name$_;\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h index 2dff3144..c1704fc1 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h @@ -53,7 +53,9 @@ class MessageFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; + void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; @@ -78,7 +80,9 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator { ~MessageOneofFieldGenerator(); // implements FieldGenerator --------------------------------------- - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; + void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {} void GenerateClearingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; void GenerateConstructorCode(io::Printer* printer) const; @@ -96,7 +100,8 @@ class RepeatedMessageFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc index 9a2c930e..329eae32 100644 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc @@ -117,18 +117,20 @@ GeneratePrivateMembers(io::Printer* printer) const { void PrimitiveFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "inline $type$ $name$() const$deprecation$;\n" - "inline void set_$name$($type$ value)$deprecation$;\n"); + "$type$ $name$() const$deprecation$;\n" + "void set_$name$($type$ value)$deprecation$;\n"); } void PrimitiveFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $classname$::$name$() const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ $type$ $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return $name$_;\n" "}\n" - "inline void $classname$::set_$name$($type$ value) {\n" + "$inline$ void $classname$::set_$name$($type$ value) {\n" " $set_hasbit$\n" " $name$_ = value;\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" @@ -204,16 +206,18 @@ PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor, PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {} void PrimitiveOneofFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $classname$::$name$() const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ $type$ $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " if (has_$name$()) {\n" " return $oneof_prefix$$name$_;\n" " }\n" " return $default$;\n" "}\n" - "inline void $classname$::set_$name$($type$ value) {\n" + "$inline$ void $classname$::set_$name$($type$ value) {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -282,38 +286,40 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedPrimitiveFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, - "inline $type$ $name$(int index) const$deprecation$;\n" - "inline void set_$name$(int index, $type$ value)$deprecation$;\n" - "inline void add_$name$($type$ value)$deprecation$;\n"); + "$type$ $name$(int index) const$deprecation$;\n" + "void set_$name$(int index, $type$ value)$deprecation$;\n" + "void add_$name$($type$ value)$deprecation$;\n"); printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField< $type$ >&\n" + "const ::google::protobuf::RepeatedField< $type$ >&\n" " $name$() const$deprecation$;\n" - "inline ::google::protobuf::RepeatedField< $type$ >*\n" + "::google::protobuf::RepeatedField< $type$ >*\n" " mutable_$name$()$deprecation$;\n"); } void RepeatedPrimitiveFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline $type$ $classname$::$name$(int index) const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ $type$ $classname$::$name$(int index) const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return $name$_.Get(index);\n" "}\n" - "inline void $classname$::set_$name$(int index, $type$ value) {\n" + "$inline$ void $classname$::set_$name$(int index, $type$ value) {\n" " $name$_.Set(index, value);\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" - "inline void $classname$::add_$name$($type$ value) {\n" + "$inline$ void $classname$::add_$name$($type$ value) {\n" " $name$_.Add(value);\n" " // @@protoc_insertion_point(field_add:$full_name$)\n" "}\n"); - printer->Print(variables_, - "inline const ::google::protobuf::RepeatedField< $type$ >&\n" + printer->Print(variables, + "$inline$ const ::google::protobuf::RepeatedField< $type$ >&\n" "$classname$::$name$() const {\n" " // @@protoc_insertion_point(field_list:$full_name$)\n" " return $name$_;\n" "}\n" - "inline ::google::protobuf::RepeatedField< $type$ >*\n" + "$inline$ ::google::protobuf::RepeatedField< $type$ >*\n" "$classname$::mutable_$name$() {\n" " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n" " return &$name$_;\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h index 97b5e867..fcd7d684 100644 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.h @@ -53,7 +53,8 @@ class PrimitiveFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; @@ -78,7 +79,8 @@ class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator { ~PrimitiveOneofFieldGenerator(); // implements FieldGenerator --------------------------------------- - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; void GenerateConstructorCode(io::Printer* printer) const; @@ -97,7 +99,8 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index 04ed08c9..1a1bcd3d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -127,7 +127,11 @@ GenerateAccessorDeclarations(io::Printer* printer) const { // files that applied the ctype. The field can still be accessed via the // reflection interface since the reflection interface is independent of // the string's underlying representation. - if (descriptor_->options().ctype() != FieldOptions::STRING) { + + bool unknown_ctype = + descriptor_->options().ctype() != EffectiveStringCType(descriptor_); + + if (unknown_ctype) { printer->Outdent(); printer->Print( " private:\n" @@ -136,23 +140,23 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } printer->Print(variables_, - "inline const ::std::string& $name$() const$deprecation$;\n" - "inline void set_$name$(const ::std::string& value)$deprecation$;\n" - "inline void set_$name$(const char* value)$deprecation$;\n" - "inline void set_$name$(const $pointer_type$* value, size_t size)" + "const ::std::string& $name$() const$deprecation$;\n" + "void set_$name$(const ::std::string& value)$deprecation$;\n" + "void set_$name$(const char* value)$deprecation$;\n" + "void set_$name$(const $pointer_type$* value, size_t size)" "$deprecation$;\n" - "inline ::std::string* mutable_$name$()$deprecation$;\n" - "inline ::std::string* $release_name$()$deprecation$;\n" - "inline void set_allocated_$name$(::std::string* $name$)$deprecation$;\n"); + "::std::string* mutable_$name$()$deprecation$;\n" + "::std::string* $release_name$()$deprecation$;\n" + "void set_allocated_$name$(::std::string* $name$)$deprecation$;\n"); if (SupportsArenas(descriptor_)) { printer->Print(variables_, - "inline ::std::string* unsafe_arena_release_$name$()$deprecation$;\n" - "inline void unsafe_arena_set_allocated_$name$(\n" + "::std::string* unsafe_arena_release_$name$()$deprecation$;\n" + "void unsafe_arena_set_allocated_$name$(\n" " ::std::string* $name$)$deprecation$;\n"); } - if (descriptor_->options().ctype() != FieldOptions::STRING) { + if (unknown_ctype) { printer->Outdent(); printer->Print(" public:\n"); printer->Indent(); @@ -160,25 +164,28 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } void StringFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; if (SupportsArenas(descriptor_)) { - printer->Print(variables_, - "inline const ::std::string& $classname$::$name$() const {\n" + printer->Print(variables, + "$inline$ const ::std::string& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return $name$_.Get($default_variable$);\n" "}\n" - "inline void $classname$::set_$name$(const ::std::string& value) {\n" + "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n" " $set_hasbit$\n" " $name$_.Set($default_variable$, value, GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" + "$inline$ void $classname$::set_$name$(const char* value) {\n" " $set_hasbit$\n" " $name$_.Set($default_variable$, $string_piece$(value),\n" " GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n" - "inline " + "$inline$ " "void $classname$::set_$name$(const $pointer_type$* value,\n" " size_t size) {\n" " $set_hasbit$\n" @@ -186,22 +193,22 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " reinterpret_cast<const char*>(value), size), GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" "}\n" - "inline ::std::string* $classname$::mutable_$name$() {\n" + "$inline$ ::std::string* $classname$::mutable_$name$() {\n" " $set_hasbit$\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $name$_.Mutable($default_variable$, GetArenaNoVirtual());\n" "}\n" - "inline ::std::string* $classname$::$release_name$() {\n" + "$inline$ ::std::string* $classname$::$release_name$() {\n" " $clear_hasbit$\n" " return $name$_.Release($default_variable$, GetArenaNoVirtual());\n" "}\n" - "inline ::std::string* $classname$::unsafe_arena_release_$name$() {\n" + "$inline$ ::std::string* $classname$::unsafe_arena_release_$name$() {\n" " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" " $clear_hasbit$\n" " return $name$_.UnsafeArenaRelease($default_variable$,\n" " GetArenaNoVirtual());\n" "}\n" - "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" + "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n" " if ($name$ != NULL) {\n" " $set_hasbit$\n" " } else {\n" @@ -211,7 +218,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" "}\n" - "inline void $classname$::unsafe_arena_set_allocated_$name$(\n" + "$inline$ void $classname$::unsafe_arena_set_allocated_$name$(\n" " ::std::string* $name$) {\n" " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" " if ($name$ != NULL) {\n" @@ -226,22 +233,22 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { "}\n"); } else { // No-arena case. - printer->Print(variables_, - "inline const ::std::string& $classname$::$name$() const {\n" + printer->Print(variables, + "$inline$ const ::std::string& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return $name$_.GetNoArena($default_variable$);\n" "}\n" - "inline void $classname$::set_$name$(const ::std::string& value) {\n" + "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n" " $set_hasbit$\n" " $name$_.SetNoArena($default_variable$, value);\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" + "$inline$ void $classname$::set_$name$(const char* value) {\n" " $set_hasbit$\n" " $name$_.SetNoArena($default_variable$, $string_piece$(value));\n" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n" - "inline " + "$inline$ " "void $classname$::set_$name$(const $pointer_type$* value, " "size_t size) {\n" " $set_hasbit$\n" @@ -249,16 +256,16 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " $string_piece$(reinterpret_cast<const char*>(value), size));\n" " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" "}\n" - "inline ::std::string* $classname$::mutable_$name$() {\n" + "$inline$ ::std::string* $classname$::mutable_$name$() {\n" " $set_hasbit$\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $name$_.MutableNoArena($default_variable$);\n" "}\n" - "inline ::std::string* $classname$::$release_name$() {\n" + "$inline$ ::std::string* $classname$::$release_name$() {\n" " $clear_hasbit$\n" " return $name$_.ReleaseNoArena($default_variable$);\n" "}\n" - "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" + "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n" " if ($name$ != NULL) {\n" " $set_hasbit$\n" " } else {\n" @@ -422,17 +429,20 @@ StringOneofFieldGenerator(const FieldDescriptor* descriptor, StringOneofFieldGenerator::~StringOneofFieldGenerator() {} void StringOneofFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; if (SupportsArenas(descriptor_)) { - printer->Print(variables_, - "inline const ::std::string& $classname$::$name$() const {\n" + printer->Print(variables, + "$inline$ const ::std::string& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " if (has_$name$()) {\n" " return $oneof_prefix$$name$_.Get($default_variable$);\n" " }\n" " return *$default_variable$;\n" "}\n" - "inline void $classname$::set_$name$(const ::std::string& value) {\n" + "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -442,7 +452,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" + "$inline$ void $classname$::set_$name$(const char* value) {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -452,7 +462,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " $string_piece$(value), GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n" - "inline " + "$inline$ " "void $classname$::set_$name$(const $pointer_type$* value,\n" " size_t size) {\n" " if (!has_$name$()) {\n" @@ -465,7 +475,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" "}\n" - "inline ::std::string* $classname$::mutable_$name$() {\n" + "$inline$ ::std::string* $classname$::mutable_$name$() {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -475,7 +485,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" "}\n" - "inline ::std::string* $classname$::$release_name$() {\n" + "$inline$ ::std::string* $classname$::$release_name$() {\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" " return $oneof_prefix$$name$_.Release($default_variable$,\n" @@ -484,7 +494,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return NULL;\n" " }\n" "}\n" - "inline ::std::string* $classname$::unsafe_arena_release_$name$() {\n" + "$inline$ ::std::string* $classname$::unsafe_arena_release_$name$() {\n" " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" @@ -494,7 +504,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return NULL;\n" " }\n" "}\n" - "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" + "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n" " if (!has_$name$()) {\n" " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" " }\n" @@ -506,7 +516,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " }\n" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" "}\n" - "inline void $classname$::unsafe_arena_set_allocated_$name$(" + "$inline$ void $classname$::unsafe_arena_set_allocated_$name$(" "::std::string* $name$) {\n" " GOOGLE_DCHECK(GetArenaNoVirtual() != NULL);\n" " if (!has_$name$()) {\n" @@ -522,15 +532,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { "}\n"); } else { // No-arena case. - printer->Print(variables_, - "inline const ::std::string& $classname$::$name$() const {\n" + printer->Print(variables, + "$inline$ const ::std::string& $classname$::$name$() const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " if (has_$name$()) {\n" " return $oneof_prefix$$name$_.GetNoArena($default_variable$);\n" " }\n" " return *$default_variable$;\n" "}\n" - "inline void $classname$::set_$name$(const ::std::string& value) {\n" + "$inline$ void $classname$::set_$name$(const ::std::string& value) {\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" @@ -540,7 +550,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " $oneof_prefix$$name$_.SetNoArena($default_variable$, value);\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" + "$inline$ void $classname$::set_$name$(const char* value) {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -550,7 +560,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " $string_piece$(value));\n" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n" - "inline " + "$inline$ " "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" @@ -561,7 +571,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " reinterpret_cast<const char*>(value), size));\n" " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" "}\n" - "inline ::std::string* $classname$::mutable_$name$() {\n" + "$inline$ ::std::string* $classname$::mutable_$name$() {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -570,7 +580,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $oneof_prefix$$name$_.MutableNoArena($default_variable$);\n" "}\n" - "inline ::std::string* $classname$::$release_name$() {\n" + "$inline$ ::std::string* $classname$::$release_name$() {\n" " if (has_$name$()) {\n" " clear_has_$oneof_name$();\n" " return $oneof_prefix$$name$_.ReleaseNoArena($default_variable$);\n" @@ -578,7 +588,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return NULL;\n" " }\n" "}\n" - "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n" + "$inline$ void $classname$::set_allocated_$name$(::std::string* $name$) {\n" " if (!has_$name$()) {\n" " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" " }\n" @@ -670,7 +680,10 @@ GeneratePrivateMembers(io::Printer* printer) const { void RepeatedStringFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { // See comment above about unknown ctypes. - if (descriptor_->options().ctype() != FieldOptions::STRING) { + bool unknown_ctype = + descriptor_->options().ctype() != EffectiveStringCType(descriptor_); + + if (unknown_ctype) { printer->Outdent(); printer->Print( " private:\n" @@ -679,26 +692,26 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } printer->Print(variables_, - "inline const ::std::string& $name$(int index) const$deprecation$;\n" - "inline ::std::string* mutable_$name$(int index)$deprecation$;\n" - "inline void set_$name$(int index, const ::std::string& value)$deprecation$;\n" - "inline void set_$name$(int index, const char* value)$deprecation$;\n" - "inline " + "const ::std::string& $name$(int index) const$deprecation$;\n" + "::std::string* mutable_$name$(int index)$deprecation$;\n" + "void set_$name$(int index, const ::std::string& value)$deprecation$;\n" + "void set_$name$(int index, const char* value)$deprecation$;\n" + "" "void set_$name$(int index, const $pointer_type$* value, size_t size)" "$deprecation$;\n" - "inline ::std::string* add_$name$()$deprecation$;\n" - "inline void add_$name$(const ::std::string& value)$deprecation$;\n" - "inline void add_$name$(const char* value)$deprecation$;\n" - "inline void add_$name$(const $pointer_type$* value, size_t size)" + "::std::string* add_$name$()$deprecation$;\n" + "void add_$name$(const ::std::string& value)$deprecation$;\n" + "void add_$name$(const char* value)$deprecation$;\n" + "void add_$name$(const $pointer_type$* value, size_t size)" "$deprecation$;\n"); printer->Print(variables_, - "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const" + "const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const" "$deprecation$;\n" - "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()" + "::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()" "$deprecation$;\n"); - if (descriptor_->options().ctype() != FieldOptions::STRING) { + if (unknown_ctype) { printer->Outdent(); printer->Print(" public:\n"); printer->Indent(); @@ -706,54 +719,57 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } void RepeatedStringFieldGenerator:: -GenerateInlineAccessorDefinitions(io::Printer* printer) const { - printer->Print(variables_, - "inline const ::std::string& $classname$::$name$(int index) const {\n" +GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const { + map<string, string> variables(variables_); + variables["inline"] = is_inline ? "inline" : ""; + printer->Print(variables, + "$inline$ const ::std::string& $classname$::$name$(int index) const {\n" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return $name$_.$cppget$(index);\n" "}\n" - "inline ::std::string* $classname$::mutable_$name$(int index) {\n" + "$inline$ ::std::string* $classname$::mutable_$name$(int index) {\n" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return $name$_.Mutable(index);\n" "}\n" - "inline void $classname$::set_$name$(int index, const ::std::string& value) {\n" + "$inline$ void $classname$::set_$name$(int index, const ::std::string& value) {\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" " $name$_.Mutable(index)->assign(value);\n" "}\n" - "inline void $classname$::set_$name$(int index, const char* value) {\n" + "$inline$ void $classname$::set_$name$(int index, const char* value) {\n" " $name$_.Mutable(index)->assign(value);\n" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n" - "inline void " + "$inline$ void " "$classname$::set_$name$" "(int index, const $pointer_type$* value, size_t size) {\n" " $name$_.Mutable(index)->assign(\n" " reinterpret_cast<const char*>(value), size);\n" " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" "}\n" - "inline ::std::string* $classname$::add_$name$() {\n" + "$inline$ ::std::string* $classname$::add_$name$() {\n" " return $name$_.Add();\n" "}\n" - "inline void $classname$::add_$name$(const ::std::string& value) {\n" + "$inline$ void $classname$::add_$name$(const ::std::string& value) {\n" " $name$_.Add()->assign(value);\n" " // @@protoc_insertion_point(field_add:$full_name$)\n" "}\n" - "inline void $classname$::add_$name$(const char* value) {\n" + "$inline$ void $classname$::add_$name$(const char* value) {\n" " $name$_.Add()->assign(value);\n" " // @@protoc_insertion_point(field_add_char:$full_name$)\n" "}\n" - "inline void " + "$inline$ void " "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n" " $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n" " // @@protoc_insertion_point(field_add_pointer:$full_name$)\n" "}\n"); - printer->Print(variables_, - "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n" + printer->Print(variables, + "$inline$ const ::google::protobuf::RepeatedPtrField< ::std::string>&\n" "$classname$::$name$() const {\n" " // @@protoc_insertion_point(field_list:$full_name$)\n" " return $name$_;\n" "}\n" - "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n" + "$inline$ ::google::protobuf::RepeatedPtrField< ::std::string>*\n" "$classname$::mutable_$name$() {\n" " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n" " return &$name$_;\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h index 0a5ca440..d1f19cd9 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h @@ -54,7 +54,8 @@ class StringFieldGenerator : public FieldGenerator { void GeneratePrivateMembers(io::Printer* printer) const; void GenerateStaticMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; @@ -83,7 +84,8 @@ class StringOneofFieldGenerator : public StringFieldGenerator { ~StringOneofFieldGenerator(); // implements FieldGenerator --------------------------------------- - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; void GenerateConstructorCode(io::Printer* printer) const; @@ -103,7 +105,8 @@ class RepeatedStringFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; - void GenerateInlineAccessorDefinitions(io::Printer* printer) const; + void GenerateInlineAccessorDefinitions(io::Printer* printer, + bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; |