diff --git a/objectivec/GPBRuntimeTypes.h b/objectivec/GPBRuntimeTypes.h index b269f1de11..9c1083a815 100644 --- a/objectivec/GPBRuntimeTypes.h +++ b/objectivec/GPBRuntimeTypes.h @@ -144,8 +144,8 @@ typedef struct GPBExtensionRange { } GPBExtensionRange; /** - A type to represent a reference to an Objective C class. + A type to represent an Objective C class. This is actually an `objc_class` but the runtime headers will not allow us to - reference `objc_class`. + reference `objc_class`, so we have defined our own. */ -typedef struct GPBObjcClassReference GPBObjcClassReference; +typedef struct GPBObjcClass_t GPBObjcClass_t; diff --git a/objectivec/GPBUtilities_PackagePrivate.h b/objectivec/GPBUtilities_PackagePrivate.h index 336a745ca1..80d423d7e2 100644 --- a/objectivec/GPBUtilities_PackagePrivate.h +++ b/objectivec/GPBUtilities_PackagePrivate.h @@ -35,14 +35,23 @@ #import "GPBDescriptor_PackagePrivate.h" // Macros for stringifying library symbols. These are used in the generated -// PB descriptor classes wherever a library symbol name is represented as a -// string. See README.google for more information. +// GPB descriptor classes wherever a library symbol name is represented as a +// string. #define GPBStringify(S) #S #define GPBStringifySymbol(S) GPBStringify(S) #define GPBNSStringify(S) @#S #define GPBNSStringifySymbol(S) GPBNSStringify(S) +// Macros for generating a Class from a class name. These are used in +// the generated GPB descriptor classes wherever an Objective C class +// reference is needed for a generated class. +#define GPBObjCClassSymbol(name) OBJC_CLASS_$_##name +#define GPBObjCClass(name) \ + ((__bridge Class)&(GPBObjCClassSymbol(name))) +#define GPBObjCClassDeclaration(name) \ + extern const GPBObjcClass_t GPBObjCClassSymbol(name) + // Constant to internally mark when there is no has bit. #define GPBNoHasBit INT32_MAX diff --git a/objectivec/google/protobuf/Api.pbobjc.m b/objectivec/google/protobuf/Api.pbobjc.m index 1463f0dc9d..b9d644e6fe 100644 --- a/objectivec/google/protobuf/Api.pbobjc.m +++ b/objectivec/google/protobuf/Api.pbobjc.m @@ -28,16 +28,14 @@ #pragma clang diagnostic ignored "-Wdeprecated-declarations" #pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" -#pragma mark - Objective C Class references -// This somewhat arcane code forces linkage of classes from static archives by -// adding a concrete reference to the classes. -// We don't use `[Foo class]` because we need a static value for our initializer. -// This also has the added benefit of reducing size in that we don't have to -// encode the class names and look them up at runtime. -extern const GPBObjcClassReference OBJC_CLASS_$_GPBMethod; -extern const GPBObjcClassReference OBJC_CLASS_$_GPBMixin; -extern const GPBObjcClassReference OBJC_CLASS_$_GPBOption; -extern const GPBObjcClassReference OBJC_CLASS_$_GPBSourceContext; +#pragma mark - Objective C Class declarations +// Forward declarations of Objective C classes that we can use as +// static values in struct initializers. +// We don't use [Foo class] because it is not a static value. +GPBObjCClassDeclaration(GPBMethod); +GPBObjCClassDeclaration(GPBMixin); +GPBObjCClassDeclaration(GPBOption); +GPBObjCClassDeclaration(GPBSourceContext); #pragma mark - GPBApiRoot @@ -103,7 +101,7 @@ typedef struct GPBApi__storage_ { }, { .name = "methodsArray", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBMethod), + .dataTypeSpecific.clazz = GPBObjCClass(GPBMethod), .number = GPBApi_FieldNumber_MethodsArray, .hasIndex = GPBNoHasBit, .offset = (uint32_t)offsetof(GPBApi__storage_, methodsArray), @@ -112,7 +110,7 @@ typedef struct GPBApi__storage_ { }, { .name = "optionsArray", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBOption), + .dataTypeSpecific.clazz = GPBObjCClass(GPBOption), .number = GPBApi_FieldNumber_OptionsArray, .hasIndex = GPBNoHasBit, .offset = (uint32_t)offsetof(GPBApi__storage_, optionsArray), @@ -130,7 +128,7 @@ typedef struct GPBApi__storage_ { }, { .name = "sourceContext", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBSourceContext), + .dataTypeSpecific.clazz = GPBObjCClass(GPBSourceContext), .number = GPBApi_FieldNumber_SourceContext, .hasIndex = 2, .offset = (uint32_t)offsetof(GPBApi__storage_, sourceContext), @@ -139,7 +137,7 @@ typedef struct GPBApi__storage_ { }, { .name = "mixinsArray", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBMixin), + .dataTypeSpecific.clazz = GPBObjCClass(GPBMixin), .number = GPBApi_FieldNumber_MixinsArray, .hasIndex = GPBNoHasBit, .offset = (uint32_t)offsetof(GPBApi__storage_, mixinsArray), @@ -260,7 +258,7 @@ typedef struct GPBMethod__storage_ { }, { .name = "optionsArray", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBOption), + .dataTypeSpecific.clazz = GPBObjCClass(GPBOption), .number = GPBMethod_FieldNumber_OptionsArray, .hasIndex = GPBNoHasBit, .offset = (uint32_t)offsetof(GPBMethod__storage_, optionsArray), diff --git a/objectivec/google/protobuf/Struct.pbobjc.m b/objectivec/google/protobuf/Struct.pbobjc.m index e8e181b254..d36be9c295 100644 --- a/objectivec/google/protobuf/Struct.pbobjc.m +++ b/objectivec/google/protobuf/Struct.pbobjc.m @@ -27,15 +27,13 @@ #pragma clang diagnostic ignored "-Wdirect-ivar-access" #pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" -#pragma mark - Objective C Class references -// This somewhat arcane code forces linkage of classes from static archives by -// adding a concrete reference to the classes. -// We don't use `[Foo class]` because we need a static value for our initializer. -// This also has the added benefit of reducing size in that we don't have to -// encode the class names and look them up at runtime. -extern const GPBObjcClassReference OBJC_CLASS_$_GPBListValue; -extern const GPBObjcClassReference OBJC_CLASS_$_GPBStruct; -extern const GPBObjcClassReference OBJC_CLASS_$_GPBValue; +#pragma mark - Objective C Class declarations +// Forward declarations of Objective C classes that we can use as +// static values in struct initializers. +// We don't use [Foo class] because it is not a static value. +GPBObjCClassDeclaration(GPBListValue); +GPBObjCClassDeclaration(GPBStruct); +GPBObjCClassDeclaration(GPBValue); #pragma mark - GPBStructRoot @@ -113,7 +111,7 @@ typedef struct GPBStruct__storage_ { static GPBMessageFieldDescription fields[] = { { .name = "fields", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBValue), + .dataTypeSpecific.clazz = GPBObjCClass(GPBValue), .number = GPBStruct_FieldNumber_Fields, .hasIndex = GPBNoHasBit, .offset = (uint32_t)offsetof(GPBStruct__storage_, fields), @@ -204,7 +202,7 @@ typedef struct GPBValue__storage_ { }, { .name = "structValue", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBStruct), + .dataTypeSpecific.clazz = GPBObjCClass(GPBStruct), .number = GPBValue_FieldNumber_StructValue, .hasIndex = -1, .offset = (uint32_t)offsetof(GPBValue__storage_, structValue), @@ -213,7 +211,7 @@ typedef struct GPBValue__storage_ { }, { .name = "listValue", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBListValue), + .dataTypeSpecific.clazz = GPBObjCClass(GPBListValue), .number = GPBValue_FieldNumber_ListValue, .hasIndex = -1, .offset = (uint32_t)offsetof(GPBValue__storage_, listValue), @@ -281,7 +279,7 @@ typedef struct GPBListValue__storage_ { static GPBMessageFieldDescription fields[] = { { .name = "valuesArray", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBValue), + .dataTypeSpecific.clazz = GPBObjCClass(GPBValue), .number = GPBListValue_FieldNumber_ValuesArray, .hasIndex = GPBNoHasBit, .offset = (uint32_t)offsetof(GPBListValue__storage_, valuesArray), diff --git a/objectivec/google/protobuf/Type.pbobjc.m b/objectivec/google/protobuf/Type.pbobjc.m index 0c48e6b312..da04392760 100644 --- a/objectivec/google/protobuf/Type.pbobjc.m +++ b/objectivec/google/protobuf/Type.pbobjc.m @@ -30,17 +30,15 @@ #pragma clang diagnostic ignored "-Wdeprecated-declarations" #pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" -#pragma mark - Objective C Class references -// This somewhat arcane code forces linkage of classes from static archives by -// adding a concrete reference to the classes. -// We don't use `[Foo class]` because we need a static value for our initializer. -// This also has the added benefit of reducing size in that we don't have to -// encode the class names and look them up at runtime. -extern const GPBObjcClassReference OBJC_CLASS_$_GPBAny; -extern const GPBObjcClassReference OBJC_CLASS_$_GPBEnumValue; -extern const GPBObjcClassReference OBJC_CLASS_$_GPBField; -extern const GPBObjcClassReference OBJC_CLASS_$_GPBOption; -extern const GPBObjcClassReference OBJC_CLASS_$_GPBSourceContext; +#pragma mark - Objective C Class declarations +// Forward declarations of Objective C classes that we can use as +// static values in struct initializers. +// We don't use [Foo class] because it is not a static value. +GPBObjCClassDeclaration(GPBAny); +GPBObjCClassDeclaration(GPBEnumValue); +GPBObjCClassDeclaration(GPBField); +GPBObjCClassDeclaration(GPBOption); +GPBObjCClassDeclaration(GPBSourceContext); #pragma mark - GPBTypeRoot @@ -139,7 +137,7 @@ typedef struct GPBType__storage_ { }, { .name = "fieldsArray", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBField), + .dataTypeSpecific.clazz = GPBObjCClass(GPBField), .number = GPBType_FieldNumber_FieldsArray, .hasIndex = GPBNoHasBit, .offset = (uint32_t)offsetof(GPBType__storage_, fieldsArray), @@ -157,7 +155,7 @@ typedef struct GPBType__storage_ { }, { .name = "optionsArray", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBOption), + .dataTypeSpecific.clazz = GPBObjCClass(GPBOption), .number = GPBType_FieldNumber_OptionsArray, .hasIndex = GPBNoHasBit, .offset = (uint32_t)offsetof(GPBType__storage_, optionsArray), @@ -166,7 +164,7 @@ typedef struct GPBType__storage_ { }, { .name = "sourceContext", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBSourceContext), + .dataTypeSpecific.clazz = GPBObjCClass(GPBSourceContext), .number = GPBType_FieldNumber_SourceContext, .hasIndex = 1, .offset = (uint32_t)offsetof(GPBType__storage_, sourceContext), @@ -312,7 +310,7 @@ typedef struct GPBField__storage_ { }, { .name = "optionsArray", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBOption), + .dataTypeSpecific.clazz = GPBObjCClass(GPBOption), .number = GPBField_FieldNumber_OptionsArray, .hasIndex = GPBNoHasBit, .offset = (uint32_t)offsetof(GPBField__storage_, optionsArray), @@ -535,7 +533,7 @@ typedef struct GPBEnum__storage_ { }, { .name = "enumvalueArray", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBEnumValue), + .dataTypeSpecific.clazz = GPBObjCClass(GPBEnumValue), .number = GPBEnum_FieldNumber_EnumvalueArray, .hasIndex = GPBNoHasBit, .offset = (uint32_t)offsetof(GPBEnum__storage_, enumvalueArray), @@ -544,7 +542,7 @@ typedef struct GPBEnum__storage_ { }, { .name = "optionsArray", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBOption), + .dataTypeSpecific.clazz = GPBObjCClass(GPBOption), .number = GPBEnum_FieldNumber_OptionsArray, .hasIndex = GPBNoHasBit, .offset = (uint32_t)offsetof(GPBEnum__storage_, optionsArray), @@ -553,7 +551,7 @@ typedef struct GPBEnum__storage_ { }, { .name = "sourceContext", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBSourceContext), + .dataTypeSpecific.clazz = GPBObjCClass(GPBSourceContext), .number = GPBEnum_FieldNumber_SourceContext, .hasIndex = 1, .offset = (uint32_t)offsetof(GPBEnum__storage_, sourceContext), @@ -641,7 +639,7 @@ typedef struct GPBEnumValue__storage_ { }, { .name = "optionsArray", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBOption), + .dataTypeSpecific.clazz = GPBObjCClass(GPBOption), .number = GPBEnumValue_FieldNumber_OptionsArray, .hasIndex = GPBNoHasBit, .offset = (uint32_t)offsetof(GPBEnumValue__storage_, optionsArray), @@ -697,7 +695,7 @@ typedef struct GPBOption__storage_ { }, { .name = "value", - .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBAny), + .dataTypeSpecific.clazz = GPBObjCClass(GPBAny), .number = GPBOption_FieldNumber_Value, .hasIndex = 1, .offset = (uint32_t)offsetof(GPBOption__storage_, value), diff --git a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc index a67d1a2eba..b514b8a72a 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc @@ -85,7 +85,7 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization( std::map vars; vars["root_class_and_method_name"] = root_class_and_method_name_; const string containing_type = ClassName(descriptor_->containing_type()); - vars["extended_type"] = ObjCClassSymbolReference(containing_type); + vars["extended_type"] = ObjCClass(containing_type); vars["number"] = StrCat(descriptor_->number()); std::vector options; @@ -99,7 +99,7 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization( ObjectiveCType objc_type = GetObjectiveCType(descriptor_); if (objc_type == OBJECTIVECTYPE_MESSAGE) { std::string message_type = ClassName(descriptor_->message_type()); - vars["type"] = ObjCClassSymbolReference(message_type); + vars["type"] = ObjCClass(message_type); } else { vars["type"] = "Nil"; } @@ -136,11 +136,11 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization( void ExtensionGenerator::DetermineObjectiveCClassDefinitions( std::set* fwd_decls) { string extended_type = ClassName(descriptor_->containing_type()); - fwd_decls->insert(ObjCClassSymbolDefinition(extended_type)); + fwd_decls->insert(ObjCClassDeclaration(extended_type)); ObjectiveCType objc_type = GetObjectiveCType(descriptor_); if (objc_type == OBJECTIVECTYPE_MESSAGE) { string message_type = ClassName(descriptor_->message_type()); - fwd_decls->insert(ObjCClassSymbolDefinition(message_type)); + fwd_decls->insert(ObjCClassDeclaration(message_type)); } } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc index c05a77daeb..e90b22bb38 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc @@ -432,12 +432,10 @@ void FileGenerator::GenerateSource(io::Printer *printer) { "\n"); if (!fwd_decls.empty()) { printer->Print( - "#pragma mark - Objective C Class references\n" - "// This somewhat arcane code forces linkage of classes from static archives by\n" - "// adding a concrete reference to the classes.\n" - "// We don't use `[Foo class]` because we need a static value for our initializer.\n" - "// This also has the added benefit of reducing size in that we don't have to\n" - "// encode the class names and look them up at runtime.\n"); + "#pragma mark - Objective C Class declarations\n" + "// Forward declarations of Objective C classes that we can use as\n" + "// static values in struct initializers.\n" + "// We don't use [Foo class] because it is not a static value.\n"); } for (const auto& i : fwd_decls) { printer->Print("$value$\n", "value", i); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index 97bc75be96..75418982ea 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -585,17 +585,12 @@ string OneofNameCapitalized(const OneofDescriptor* descriptor) { return result; } -static string ObjCClassSymbolName(const string& class_name) { - return string("OBJC_CLASS_$_") + class_name; +string ObjCClass(const string& class_name) { + return string("GPBObjCClass(") + class_name + ")"; } -string ObjCClassSymbolReference(const string& class_name) { - return "((__bridge Class)&" + ObjCClassSymbolName(class_name) + ")"; -} - -string ObjCClassSymbolDefinition(const string& class_name) { - const string &ref = ObjCClassSymbolName(class_name); - return "extern const GPBObjcClassReference " + ref + ";"; +string ObjCClassDeclaration(const string& class_name) { + return string("GPBObjCClassDeclaration(") + class_name + ");"; } string UnCamelCaseFieldName(const string& name, const FieldDescriptor* field) { diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h index b170d9857f..c6a2c7733b 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -120,12 +120,11 @@ string PROTOC_EXPORT OneofNameCapitalized(const OneofDescriptor* descriptor); // Returns a symbol that can be used in C code to refer to an Objective C // class without initializing the class. -string PROTOC_EXPORT ObjCClassSymbolReference(const string& class_name); +string PROTOC_EXPORT ObjCClass(const string& class_name); -// Defines a symbol that can be used in C code to refer to an Objective C -// class without initializing the class. Use a corresponding -// ObjCClassSymbolReference to reference it. -string PROTOC_EXPORT ObjCClassSymbolDefinition(const string& class_name); +// Declares an Objective C class without initializing the class so that it can +// be refrerred to by ObjCClass. +string PROTOC_EXPORT ObjCClassDeclaration(const string& class_name); inline bool HasFieldPresence(const FileDescriptor* file) { return file->syntax() != FileDescriptor::SYNTAX_PROTO3; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc index 55e5bf9da6..3b8eaa040d 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc @@ -177,7 +177,7 @@ void MapFieldGenerator::DetermineObjectiveCClassDefinitions( const FieldDescriptor* value_descriptor = descriptor_->message_type()->FindFieldByName("value"); if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { - fwd_decls->insert(ObjCClassSymbolDefinition( + fwd_decls->insert(ObjCClassDeclaration( value_field_generator_->variable("storage_type"))); } } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/src/google/protobuf/compiler/objectivec/objectivec_message.cc index af13c145a8..2a0e40231d 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_message.cc @@ -254,7 +254,7 @@ void MessageGenerator::DetermineObjectiveCClassDefinitions(std::set* fwd const Descriptor* containing_descriptor = descriptor_->containing_type(); if (containing_descriptor != NULL) { string containing_class = ClassName(containing_descriptor); - fwd_decls->insert(ObjCClassSymbolDefinition(containing_class)); + fwd_decls->insert(ObjCClassDeclaration(containing_class)); } } @@ -582,7 +582,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { } if (descriptor_->containing_type() != NULL) { string containing_class = ClassName(descriptor_->containing_type()); - string parent_class_ref = ObjCClassSymbolReference(containing_class); + string parent_class_ref = ObjCClass(containing_class); printer->Print( " [localDescriptor setupContainingMessageClass:$parent_class_ref$];\n", "parent_class_ref", parent_class_ref); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc index 93b75571c2..2730e7591d 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc @@ -52,8 +52,7 @@ void SetMessageVariables(const FieldDescriptor* descriptor, (*variables)["storage_type"] = message_type; (*variables)["group_or_message"] = (descriptor->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message"; - (*variables)["dataTypeSpecific_value"] = - ObjCClassSymbolReference(message_type); + (*variables)["dataTypeSpecific_value"] = ObjCClass(message_type); } } // namespace @@ -75,7 +74,7 @@ void MessageFieldGenerator::DetermineForwardDeclarations( void MessageFieldGenerator::DetermineObjectiveCClassDefinitions( std::set* fwd_decls) const { - fwd_decls->insert(ObjCClassSymbolDefinition(variable("storage_type"))); + fwd_decls->insert(ObjCClassDeclaration(variable("storage_type"))); } bool MessageFieldGenerator::WantsHasProperty(void) const { @@ -108,7 +107,7 @@ void RepeatedMessageFieldGenerator::DetermineForwardDeclarations( void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions( std::set* fwd_decls) const { - fwd_decls->insert(ObjCClassSymbolDefinition(variable("storage_type"))); + fwd_decls->insert(ObjCClassDeclaration(variable("storage_type"))); } } // namespace objectivec