]> git.saurik.com Git - apple/ld64.git/blobdiff - src/ld/passes/objc.cpp
ld64-242.tar.gz
[apple/ld64.git] / src / ld / passes / objc.cpp
index d921a64fb515100d69668828fa22fc6c6b0721a6..2bbf54a61ead25d474a8c83fcf25e5b671d59b61 100644 (file)
@@ -65,7 +65,7 @@ template <typename A>
 class ObjCImageInfoAtom : public ld::Atom {
 public:
                                                                                        ObjCImageInfoAtom(ld::File::ObjcConstraint objcConstraint, 
-                                                                                                                       bool compaction, bool abi2);
+                                                                                                                       bool compaction, bool abi2, uint8_t swiftVersion);
 
        virtual const ld::File*                                 file() const                                    { return NULL; }
        virtual const char*                                             name() const                                    { return "objc image info"; }
@@ -89,7 +89,7 @@ template <typename A> ld::Section ObjCImageInfoAtom<A>::_s_sectionABI2("__DATA",
 
 template <typename A>
 ObjCImageInfoAtom<A>::ObjCImageInfoAtom(ld::File::ObjcConstraint objcConstraint, bool compaction, 
-                                                                               bool abi2)
+                                                                               bool abi2, uint8_t swiftVersion)
        : ld::Atom(abi2 ? _s_sectionABI2 : _s_sectionABI1, ld::Atom::definitionRegular, ld::Atom::combineNever,
                                                        ld::Atom::scopeLinkageUnit, ld::Atom::typeUnclassified, 
                                                        symbolTableNotIn, false, false, false, ld::Atom::Alignment(2))
@@ -117,6 +117,9 @@ ObjCImageInfoAtom<A>::ObjCImageInfoAtom(ld::File::ObjcConstraint objcConstraint,
                        break;
        }
 
+       // provide swift language version in final binary for runtime to inspect
+       value |= (swiftVersion << 8);
+
        _content.version = 0;
        A::P::E::set32(_content.flags, value);
 }
@@ -362,7 +365,7 @@ void ObjCData<A>::setPointerInContent(ld::Internal& state, const ld::Atom* conte
 template <typename A>
 class Category : public ObjCData<A> {
 public:
-       static const ld::Atom*  getClass(ld::Internal& state, const ld::Atom* contentAtom);
+       static const ld::Atom*  getClass(ld::Internal& state, const ld::Atom* contentAtom, bool& hasAddend);
        static const ld::Atom*  getInstanceMethods(ld::Internal& state, const ld::Atom* contentAtom);
        static const ld::Atom*  getClassMethods(ld::Internal& state, const ld::Atom* contentAtom);
        static const ld::Atom*  getProtocols(ld::Internal& state, const ld::Atom* contentAtom);
@@ -374,9 +377,9 @@ private:
 
 
 template <typename A>
-const ld::Atom*        Category<A>::getClass(ld::Internal& state, const ld::Atom* contentAtom)
+const ld::Atom*        Category<A>::getClass(ld::Internal& state, const ld::Atom* contentAtom, bool& hasAddend)
 {
-       return ObjCData<A>::getPointerInContent(state, contentAtom, sizeof(pint_t)); // category_t.cls
+       return ObjCData<A>::getPointerInContent(state, contentAtom, sizeof(pint_t), &hasAddend); // category_t.cls
 }
 
 template <typename A>
@@ -838,10 +841,17 @@ void OptimizeCategories<A>::doit(const Options& opts, ld::Internal& state)
                                // ignore categories also in __objc_nlcatlist
                                if ( nlcatListAtoms.count(categoryAtom) != 0 )
                                        continue;
-                               const ld::Atom* categoryOnClassAtom = Category<A>::getClass(state, categoryAtom); 
+                               const ld::Atom* categoryOnClassAtom = Category<A>::getClass(state, categoryAtom, hasAddend); 
                                assert(categoryOnClassAtom != NULL);
+                               // only look at classes defined in this image
                                if ( categoryOnClassAtom->definition() != ld::Atom::definitionProxy ) {
-                                       // only look at classes defined in this image
+                                       // <rdar://problem/16107696> for now, back off optimization on new style classes
+                                       if ( hasAddend != 0 )
+                                               continue;
+                                       // <rdar://problem/17249777> don't apply categories to swift classes
+                                       if ( categoryOnClassAtom->hasFixupsOfKind(ld::Fixup::kindNoneGroupSubordinate) )
+                                               continue;
+
                                        CatMap::iterator pos = classToCategories.find(categoryOnClassAtom);
                                        if ( pos == classToCategories.end() ) {
                                                classToCategories[categoryOnClassAtom] = new std::vector<const ld::Atom*>();
@@ -1171,25 +1181,25 @@ void doPass(const Options& opts, ld::Internal& state)
 #if SUPPORT_ARCH_x86_64
                        case CPU_TYPE_X86_64:
                                state.addAtom(*new ObjCImageInfoAtom<x86_64>(state.objcObjectConstraint, compaction, 
-                                                               true));
+                                                         true, state.swiftVersion));
                                break;
 #endif
 #if SUPPORT_ARCH_i386
                        case CPU_TYPE_I386:
                                state.addAtom(*new ObjCImageInfoAtom<x86>(state.objcObjectConstraint, compaction, 
-                                                       opts.objCABIVersion2POverride() ? true : false));
+                                                         opts.objCABIVersion2POverride() ? true : false, state.swiftVersion));
                                break;
 #endif
 #if SUPPORT_ARCH_arm_any
                        case CPU_TYPE_ARM:
                                state.addAtom(*new ObjCImageInfoAtom<arm>(state.objcObjectConstraint, compaction, 
-                                                       true));
+                                                         true, state.swiftVersion));
                                break;
 #endif
 #if SUPPORT_ARCH_arm64
                        case CPU_TYPE_ARM64:
                                state.addAtom(*new ObjCImageInfoAtom<arm64>(state.objcObjectConstraint, compaction, 
-                                                       true));
+                                                         true, state.swiftVersion));
                                break;
 #endif
                        default: