diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp index 6c39e4b72c7..dcbaa6dfec5 100644 --- a/lib/IRGen/GenClass.cpp +++ b/lib/IRGen/GenClass.cpp @@ -1520,33 +1520,27 @@ namespace { } void buildMethod(ConstantArrayBuilder &descriptors, - MethodDescriptor descriptor, - llvm::StringSet<> &uniqueSelectors) { + MethodDescriptor descriptor) { switch (descriptor.getKind()) { case MethodDescriptor::Kind::Method: - return buildMethod(descriptors, descriptor.getMethod(), - uniqueSelectors); + return buildMethod(descriptors, descriptor.getMethod()); case MethodDescriptor::Kind::IVarInitializer: emitObjCIVarInitDestroyDescriptor(IGM, descriptors, getClass(), - descriptor.getImpl(), false, - uniqueSelectors); + descriptor.getImpl(), false); return; case MethodDescriptor::Kind::IVarDestroyer: emitObjCIVarInitDestroyDescriptor(IGM, descriptors, getClass(), - descriptor.getImpl(), true, - uniqueSelectors); + descriptor.getImpl(), true); return; } llvm_unreachable("bad method descriptor kind"); } void buildMethod(ConstantArrayBuilder &descriptors, - AbstractFunctionDecl *method, - llvm::StringSet<> &uniqueSelectors) { + AbstractFunctionDecl *method) { auto accessor = dyn_cast(method); if (!accessor) - return emitObjCMethodDescriptor(IGM, descriptors, method, - uniqueSelectors); + return emitObjCMethodDescriptor(IGM, descriptors, method); switch (accessor->getAccessorKind()) { case AccessorKind::Get: @@ -1615,9 +1609,7 @@ namespace { namePrefix = "_PROTOCOL_INSTANCE_METHODS_OPT_"; break; } - llvm::StringSet<> uniqueSelectors; - llvm::Constant *methodListPtr = - buildMethodList(methods, namePrefix, uniqueSelectors); + llvm::Constant *methodListPtr = buildMethodList(methods, namePrefix); builder.add(methodListPtr); } @@ -1643,15 +1635,12 @@ namespace { void buildExtMethodTypes(ConstantArrayBuilder &array, ArrayRef methods) { assert(isBuildingProtocol()); - llvm::StringSet<> uniqueSelectors; + for (auto descriptor : methods) { assert(descriptor.getKind() == MethodDescriptor::Kind::Method && "cannot emit descriptor for non-method"); auto method = descriptor.getMethod(); - auto *encodingOrNullIfDuplicate = - getMethodTypeExtendedEncoding(IGM, method, uniqueSelectors); - if (encodingOrNullIfDuplicate != nullptr) - array.add(encodingOrNullIfDuplicate); + array.add(getMethodTypeExtendedEncoding(IGM, method)); } } @@ -1663,12 +1652,11 @@ namespace { /// /// This method does not return a value of a predictable type. llvm::Constant *buildMethodList(ArrayRef methods, - StringRef name, - llvm::StringSet<> &uniqueSelectors) { + StringRef name) { return buildOptionalList(methods, 3 * IGM.getPointerSize(), name, [&](ConstantArrayBuilder &descriptors, MethodDescriptor descriptor) { - buildMethod(descriptors, descriptor, uniqueSelectors); + buildMethod(descriptors, descriptor); }); } diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp index 0041e3ef3e6..9da425db298 100644 --- a/lib/IRGen/GenObjC.cpp +++ b/lib/IRGen/GenObjC.cpp @@ -1100,41 +1100,9 @@ static llvm::Constant *getObjCEncodingForTypes(IRGenModule &IGM, return IGM.getAddrOfGlobalString(encodingString); } -static llvm::Constant * -getObjectEncodingFromClangNode(IRGenModule &IGM, Decl *d, - bool useExtendedEncoding) { - // Use the clang node's encoding if there is a clang node. - if (d->getClangNode()) { - auto clangDecl = d->getClangNode().castAsDecl(); - auto &clangASTContext = IGM.getClangASTContext(); - std::string typeStr; - if (auto objcMethodDecl = dyn_cast(clangDecl)) { - typeStr = clangASTContext.getObjCEncodingForMethodDecl( - objcMethodDecl, useExtendedEncoding /*extended*/); - } - if (auto objcPropertyDecl = dyn_cast(clangDecl)) { - typeStr = clangASTContext.getObjCEncodingForPropertyDecl(objcPropertyDecl, - nullptr); - } - if (!typeStr.empty()) { - return IGM.getAddrOfGlobalString(typeStr.c_str()); - } - } - return nullptr; -} - -static llvm::Constant *getObjCEncodingForMethod(IRGenModule &IGM, - CanSILFunctionType fnType, - bool useExtendedEncoding, - Decl *optionalDecl) { - // Use the decl's ClangNode to get the encoding if possible. - if (optionalDecl) { - if (auto *enc = getObjectEncodingFromClangNode(IGM, optionalDecl, - useExtendedEncoding)) { - return enc; - } - } - +static llvm::Constant *getObjCEncodingForMethodType(IRGenModule &IGM, + CanSILFunctionType fnType, + bool useExtendedEncoding) { // Get the inputs without 'self'. auto inputs = fnType->getParameters().drop_back(); @@ -1160,13 +1128,11 @@ irgen::emitObjCMethodDescriptorParts(IRGenModule &IGM, /// The first element is the selector. descriptor.selectorRef = IGM.getAddrOfObjCMethodName(selector.str()); - /// The second element is the method signature. A method signature is made - /// of the return type @encoding and every parameter type @encoding, glued - /// with numbers that used to represent stack offsets for each of these - /// elements. + /// The second element is the method signature. A method signature is made of + /// the return type @encoding and every parameter type @encoding, glued with + /// numbers that used to represent stack offsets for each of these elements. CanSILFunctionType methodType = getObjCMethodType(IGM, method); - descriptor.typeEncoding = - getObjCEncodingForMethod(IGM, methodType, /*extended*/ false, method); + descriptor.typeEncoding = getObjCEncodingForMethodType(IGM, methodType, /*extended*/false); /// The third element is the method implementation pointer. if (!concrete) { @@ -1225,13 +1191,10 @@ irgen::emitObjCGetterDescriptorParts(IRGenModule &IGM, Selector getterSel(subscript, Selector::ForGetter); ObjCMethodDescriptor descriptor{}; descriptor.selectorRef = IGM.getAddrOfObjCMethodName(getterSel.str()); - - auto methodTy = - getObjCMethodType(IGM, subscript->getOpaqueAccessor(AccessorKind::Get)); - descriptor.typeEncoding = - getObjCEncodingForMethod(IGM, methodTy, - /*extended*/ false, subscript); - + auto methodTy = getObjCMethodType(IGM, + subscript->getOpaqueAccessor(AccessorKind::Get)); + descriptor.typeEncoding = getObjCEncodingForMethodType(IGM, methodTy, + /*extended*/false); descriptor.silFunction = nullptr; descriptor.impl = getObjCGetterPointer(IGM, subscript, descriptor.silFunction); @@ -1303,9 +1266,8 @@ irgen::emitObjCSetterDescriptorParts(IRGenModule &IGM, descriptor.selectorRef = IGM.getAddrOfObjCMethodName(setterSel.str()); auto methodTy = getObjCMethodType(IGM, subscript->getOpaqueAccessor(AccessorKind::Set)); - descriptor.typeEncoding = - getObjCEncodingForMethod(IGM, methodTy, - /*extended*/ false, subscript); + descriptor.typeEncoding = getObjCEncodingForMethodType(IGM, methodTy, + /*extended*/false); descriptor.silFunction = nullptr; descriptor.impl = getObjCSetterPointer(IGM, subscript, descriptor.silFunction); @@ -1361,33 +1323,23 @@ static void emitObjCDescriptor(IRGenModule &IGM, /// }; void irgen::emitObjCMethodDescriptor(IRGenModule &IGM, ConstantArrayBuilder &descriptors, - AbstractFunctionDecl *method, - llvm::StringSet<> &uniqueSelectors) { - // Don't emit a selector twice. - Selector selector(method); - if (!uniqueSelectors.insert(selector.str()).second) - return; - + AbstractFunctionDecl *method) { ObjCMethodDescriptor descriptor( emitObjCMethodDescriptorParts(IGM, method, /*concrete*/ true)); emitObjCDescriptor(IGM, descriptors, descriptor); } -void irgen::emitObjCIVarInitDestroyDescriptor( - IRGenModule &IGM, ConstantArrayBuilder &descriptors, ClassDecl *cd, - llvm::Function *objcImpl, bool isDestroyer, - llvm::StringSet<> &uniqueSelectors) { +void irgen::emitObjCIVarInitDestroyDescriptor(IRGenModule &IGM, + ConstantArrayBuilder &descriptors, + ClassDecl *cd, + llvm::Function *objcImpl, + bool isDestroyer) { /// The first element is the selector. SILDeclRef declRef = SILDeclRef(cd, isDestroyer? SILDeclRef::Kind::IVarDestroyer : SILDeclRef::Kind::IVarInitializer, /*foreign*/ true); Selector selector(declRef); - - // Don't emit a selector twice. - if (!uniqueSelectors.insert(selector.str()).second) - return; - ObjCMethodDescriptor descriptor{}; descriptor.selectorRef = IGM.getAddrOfObjCMethodName(selector.str()); @@ -1406,18 +1358,11 @@ void irgen::emitObjCIVarInitDestroyDescriptor( buildMethodDescriptor(IGM, descriptors, descriptor); } - llvm::Constant * irgen::getMethodTypeExtendedEncoding(IRGenModule &IGM, - AbstractFunctionDecl *method, - llvm::StringSet<> &uniqueSelectors) { - // Don't emit a selector twice. - Selector selector(method); - if (!uniqueSelectors.insert(selector.str()).second) - return nullptr; - + AbstractFunctionDecl *method) { CanSILFunctionType methodType = getObjCMethodType(IGM, method); - return getObjCEncodingForMethod(IGM, methodType, true /*Extended*/, method); + return getObjCEncodingForMethodType(IGM, methodType, true/*Extended*/); } llvm::Constant * diff --git a/lib/IRGen/GenObjC.h b/lib/IRGen/GenObjC.h index 33d582d59ee..64ec654afc3 100644 --- a/lib/IRGen/GenObjC.h +++ b/lib/IRGen/GenObjC.h @@ -155,8 +155,7 @@ namespace irgen { /// constructor, or destructor implementation. void emitObjCMethodDescriptor(IRGenModule &IGM, ConstantArrayBuilder &descriptors, - AbstractFunctionDecl *method, - llvm::StringSet<> &uniqueSelectors); + AbstractFunctionDecl *method); /// Build an Objective-C method descriptor for the ivar initializer /// or destroyer of a class (-.cxx_construct or -.cxx_destruct). @@ -164,8 +163,7 @@ namespace irgen { ConstantArrayBuilder &descriptors, ClassDecl *cd, llvm::Function *impl, - bool isDestroyer, - llvm::StringSet<> &uniqueSelectors); + bool isDestroyer); /// Get the type encoding for an ObjC property. void getObjCEncodingForPropertyType(IRGenModule &IGM, VarDecl *property, @@ -177,12 +175,10 @@ namespace irgen { CanSILFunctionType invokeTy); /// Produces extended encoding of method type. - /// \returns the encoded type or null if it is a duplicate (exists in - /// \p uniqueSelectors). - llvm::Constant * - getMethodTypeExtendedEncoding(IRGenModule &IGM, AbstractFunctionDecl *method, - llvm::StringSet<> &uniqueSelectors); - + /// \returns the encoded type. + llvm::Constant *getMethodTypeExtendedEncoding(IRGenModule &IGM, + AbstractFunctionDecl *method); + /// Build an Objective-C method descriptor for the given getter method. void emitObjCGetterDescriptor(IRGenModule &IGM, ConstantArrayBuilder &descriptors, diff --git a/test/IRGen/Inputs/usr/include/Gizmo.h b/test/IRGen/Inputs/usr/include/Gizmo.h index b359a526b39..474f15047b0 100644 --- a/test/IRGen/Inputs/usr/include/Gizmo.h +++ b/test/IRGen/Inputs/usr/include/Gizmo.h @@ -159,7 +159,3 @@ struct StructOfNSStrings useStructOfNSStringsInObjC(struct StructOfNSStrings); __attribute__((swift_name("OuterType.InnerType"))) @interface OuterTypeInnerType : NSObject @end - -@protocol P -- (oneway void)stuff; -@end diff --git a/test/IRGen/objc_protocol_instance_methods.swift b/test/IRGen/objc_protocol_instance_methods.swift deleted file mode 100644 index d67484867b6..00000000000 --- a/test/IRGen/objc_protocol_instance_methods.swift +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-ir %s | %FileCheck %s - -// REQUIRES: OS=macosx - - -// Make sure we don't emit duplicate method descriptors - -// CHECK-NOT: _PROTOCOL_INSTANCE_METHODS_NSObject{{.*}}"\01L_selector_data(conformsToProtocol:)"{{.*}}"\01L_selector_data(conformsToProtocol:)" - -// Make sure that extended method types are in sync with entries in method list. -// CHECK: @_PROTOCOL_INSTANCE_METHODS_NSObject = private constant { i32, i32, [5 x -// CHECK: @_PROTOCOL_METHOD_TYPES_NSObject = private constant [5 -import Foundation - -@objc protocol P: NSObjectProtocol {} -class C: NSObject, P {} diff --git a/test/IRGen/objc_type_encoding.swift b/test/IRGen/objc_type_encoding.swift index be86229249f..29f00d6b0c4 100644 --- a/test/IRGen/objc_type_encoding.swift +++ b/test/IRGen/objc_type_encoding.swift @@ -166,7 +166,6 @@ import gizmo func subclassComposition(_: MyCustomObject & NSRuncing & NSFunging) } - // CHECK-macosx: [[ENC1:@.*]] = private unnamed_addr constant [35 x i8] c"v24@0:8@\22\2216\00" // CHECK-macosx: [[ENC2:@.*]] = private unnamed_addr constant [46 x i8] c"v32@0:8@\22Gizmo\2216@?24\00" // CHECK-macosx: [[ENC3:@.*]] = private unnamed_addr constant [53 x i8] c"v24@0:8@\22_TtC18objc_type_encoding14MyCustomObject\2216\00" @@ -182,10 +181,3 @@ import gizmo // CHECK-tvos: [[ENC3:@.*]] = private unnamed_addr constant [53 x i8] c"v24@0:8@\22_TtC18objc_type_encoding14MyCustomObject\2216\00" // CHECK-tvos: [[ENC4:@.*]] = private unnamed_addr constant [75 x i8] c"v24@0:8@\22_TtC18objc_type_encoding14MyCustomObject\2216\00" // CHECK-tvos: @_PROTOCOL_METHOD_TYPES__TtP18objc_type_encoding10MyProtocol_ = private constant [4 x i8*] [i8* getelementptr inbounds ([35 x i8], [35 x i8]* [[ENC1]], i64 0, i64 0), i8* getelementptr inbounds ([46 x i8], [46 x i8]* [[ENC2]], i64 0, i64 0), i8* getelementptr inbounds ([53 x i8], [53 x i8]* [[ENC3]], i64 0, i64 0), i8* getelementptr inbounds ([75 x i8], [75 x i8]* [[ENC4]], i64 0, i64 0)] - -class C: P { - func stuff() {} -} - -// CHECK-macosx: [[ENC5:@.*]] = private unnamed_addr constant [9 x i8] c"Vv16@0:8\00" -// CHECK-macosx: @_PROTOCOL_INSTANCE_METHODS_P = {{.*}}@"\01L_selector_data(stuff)"{{.*}}[[ENC5]]{{.*}}, section "__DATA, __objc_const", align 8