Merge pull request #30667 from aschwaighofer/revert_objc_protocol_method_uniquing

Revert "Merge pull request #30612 from aschwaighofer/irgen_also_uniqu…
This commit is contained in:
Arnold Schwaighofer
2020-03-27 08:36:53 -07:00
committed by GitHub
6 changed files with 38 additions and 137 deletions

View File

@@ -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<AccessorDecl>(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<MethodDescriptor> 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<MethodDescriptor> 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);
});
}

View File

@@ -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<clang::ObjCMethodDecl>(clangDecl)) {
typeStr = clangASTContext.getObjCEncodingForMethodDecl(
objcMethodDecl, useExtendedEncoding /*extended*/);
}
if (auto objcPropertyDecl = dyn_cast<clang::ObjCPropertyDecl>(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 *

View File

@@ -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,11 +175,9 @@ 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,

View File

@@ -159,7 +159,3 @@ struct StructOfNSStrings useStructOfNSStringsInObjC(struct StructOfNSStrings);
__attribute__((swift_name("OuterType.InnerType")))
@interface OuterTypeInnerType : NSObject<NSRuncing>
@end
@protocol P
- (oneway void)stuff;
@end

View File

@@ -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 {}

View File

@@ -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<NSFunging><NSRuncing>\2216\00"
// CHECK-macosx: [[ENC2:@.*]] = private unnamed_addr constant [46 x i8] c"v32@0:8@\22Gizmo\2216@?<v@?@\22NSView\22@\22NSSpoon\22>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<NSFunging><NSRuncing>\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