+ OptimizeCategories<A>::doit(opts, state);
+ }
+
+ // Search for surviving categories that have a non-null class properties field.
+ // Search for surviving categories that do not have storage for the class properties field.
+ bool haveCategoriesWithNonNullClassProperties;
+ bool haveCategoriesWithoutClassPropertyStorage;
+ scanCategories<A>(state, haveCategoriesWithNonNullClassProperties, haveCategoriesWithoutClassPropertyStorage);
+
+ // Complain about mismatched category ABI.
+ // These can't be combined into a single linkage unit because there is only one size indicator for all categories in the file.
+ // If there is a mismatch then we don't set the HasCategoryClassProperties bit in the output file,
+ // which has at runtime causes any class property metadata that was present to be ignored.
+ if (haveCategoriesWithNonNullClassProperties && haveCategoriesWithoutClassPropertyStorage) {
+ warning("Some object files have incompatible Objective-C category definitions. Some category metadata may be lost. All files containing Objective-C categories should be built using the same compiler.");
+ }
+
+ // add image info atom
+ // The HasCategoryClassProperties bit is set as often as possible.
+ state.addAtom(*new ObjCImageInfoAtom<A>(state.objcObjectConstraint, opts.objcGcCompaction(), isObjC2,
+ !haveCategoriesWithoutClassPropertyStorage, state.swiftVersion));
+}
+
+
+void doPass(const Options& opts, ld::Internal& state)
+{
+ switch ( opts.architecture() ) {