Merge pull request #63534 from beccadax/default-is-not-init-stars

Make objcImpl classes derive inherited inits
This commit is contained in:
Becca Royal-Gordon
2023-02-09 12:02:44 -08:00
committed by GitHub
6 changed files with 78 additions and 23 deletions

View File

@@ -1068,7 +1068,8 @@ emitMemberInit(SILGenFunction &SGF, VarDecl *selfDecl, Pattern *pattern) {
slot = SGF.B.createStructElementAddr(pattern, self.forward(SGF), field,
fieldTy.getAddressType());
} else {
assert(isa<ClassDecl>(field->getDeclContext()));
assert(isa<ClassDecl>(field->getDeclContext()->
getImplementedObjCContext()));
slot = SGF.B.createRefElementAddr(pattern, self.forward(SGF), field,
fieldTy.getAddressType());
}
@@ -1165,7 +1166,7 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
NominalTypeDecl *nominal) {
auto subs = getSubstitutionsForPropertyInitializer(dc, nominal);
for (auto member : nominal->getMembers()) {
for (auto member : nominal->getImplementationContext()->getMembers()) {
// Find instance pattern binding declarations that have initializers.
if (auto pbd = dyn_cast<PatternBindingDecl>(member)) {
if (pbd->isStatic()) continue;

View File

@@ -468,12 +468,26 @@ createDesignatedInitOverrideGenericParams(ASTContext &ctx,
ArrayRef<RequirementRepr>(), SourceLoc());
}
/// True if the type has an opaque clang implementation, meaning it is imported
/// and doesn't have an \c \@objcImplementation extension.
static bool hasClangImplementation(const NominalTypeDecl *decl) {
return decl->hasClangNode() && !decl->getObjCImplementationDecl();
}
/// True if \p member is in the main body of \p ty, where the "main body" is
/// either the type itself (the usual case) or its \c \@objcImplementation
/// extension (if one is present).
static bool isInMainBody(ValueDecl *member, NominalTypeDecl *ty) {
return member->getDeclContext() ==
ty->getImplementationContext()->getAsGenericContext();
}
static void
configureInheritedDesignatedInitAttributes(ClassDecl *classDecl,
ConstructorDecl *ctor,
ConstructorDecl *superclassCtor,
ASTContext &ctx) {
assert(ctor->getDeclContext() == classDecl);
assert(isInMainBody(ctor, classDecl));
AccessLevel access = classDecl->getFormalAccess();
access = std::max(access, AccessLevel::Internal);
@@ -705,6 +719,7 @@ createDesignatedInitOverride(ClassDecl *classDecl,
// Create the initializer declaration, inheriting the name,
// failability, and throws from the superclass initializer.
auto implCtx = classDecl->getImplementationContext()->getAsGenericContext();
auto ctor =
new (ctx) ConstructorDecl(superclassCtor->getName(),
classDecl->getBraces().Start,
@@ -714,8 +729,7 @@ createDesignatedInitOverride(ClassDecl *classDecl,
/*AsyncLoc=*/SourceLoc(),
/*Throws=*/superclassCtor->hasThrows(),
/*ThrowsLoc=*/SourceLoc(),
bodyParams, genericParams,
classDecl);
bodyParams, genericParams, implCtx);
ctor->setImplicit();
@@ -837,9 +851,9 @@ static void diagnoseMissingRequiredInitializer(
bool AreAllStoredPropertiesDefaultInitableRequest::evaluate(
Evaluator &evaluator, NominalTypeDecl *decl) const {
assert(!decl->hasClangNode());
assert(!hasClangImplementation(decl));
for (auto member : decl->getMembers()) {
for (auto member : decl->getImplementationContext()->getMembers()) {
// If a stored property lacks an initial value and if there is no way to
// synthesize an initial value (e.g. for an optional) then we suppress
// generation of the default initializer.
@@ -880,7 +894,7 @@ bool AreAllStoredPropertiesDefaultInitableRequest::evaluate(
static bool areAllStoredPropertiesDefaultInitializable(Evaluator &eval,
NominalTypeDecl *decl) {
if (decl->hasClangNode())
if (hasClangImplementation(decl))
return true;
return evaluateOrDefault(
@@ -890,11 +904,11 @@ static bool areAllStoredPropertiesDefaultInitializable(Evaluator &eval,
bool
HasUserDefinedDesignatedInitRequest::evaluate(Evaluator &evaluator,
NominalTypeDecl *decl) const {
assert(!decl->hasClangNode());
assert(!hasClangImplementation(decl));
auto results = decl->lookupDirect(DeclBaseName::createConstructor());
for (auto *member : results) {
if (isa<ExtensionDecl>(member->getDeclContext()))
if (!isInMainBody(member, decl))
continue;
auto *ctor = cast<ConstructorDecl>(member);
@@ -908,7 +922,7 @@ HasUserDefinedDesignatedInitRequest::evaluate(Evaluator &evaluator,
static bool hasUserDefinedDesignatedInit(Evaluator &eval,
NominalTypeDecl *decl) {
// Imported decls don't have a designated initializer defined by the user.
if (decl->hasClangNode())
if (hasClangImplementation(decl))
return false;
return evaluateOrDefault(eval, HasUserDefinedDesignatedInitRequest{decl},
@@ -935,7 +949,7 @@ static void collectNonOveriddenSuperclassInits(
auto ctors = subclass->lookupDirect(DeclBaseName::createConstructor());
for (auto *member : ctors) {
if (isa<ExtensionDecl>(member->getDeclContext()))
if (!isInMainBody(member, subclass))
continue;
auto *ctor = cast<ConstructorDecl>(member);
@@ -1038,7 +1052,7 @@ static void addImplicitInheritedConstructorsToClass(ClassDecl *decl) {
auto results = decl->lookupDirect(DeclBaseName::createConstructor());
for (auto *member : results) {
if (isa<ExtensionDecl>(member->getDeclContext()))
if (!isInMainBody(member, decl))
continue;
auto *ctor = cast<ConstructorDecl>(member);
@@ -1066,7 +1080,7 @@ static void addImplicitInheritedConstructorsToClass(ClassDecl *decl) {
if (auto ctor = createDesignatedInitOverride(
decl, superclassCtor, kind, ctx)) {
decl->addMember(ctor);
decl->getImplementationContext()->addMember(ctor);
}
}
}
@@ -1107,7 +1121,7 @@ InheritsSuperclassInitializersRequest::evaluate(Evaluator &eval,
static bool shouldAttemptInitializerSynthesis(const NominalTypeDecl *decl) {
// Don't synthesize initializers for imported decls.
if (decl->hasClangNode())
if (hasClangImplementation(decl))
return false;
// Don't add implicit constructors in module interfaces.

View File

@@ -2737,7 +2737,7 @@ static ArrayRef<Decl *> evaluateMembersRequest(
return ctx.AllocateCopy(result);
}
auto nominal = dyn_cast<NominalTypeDecl>(idc);
auto nominal = dyn_cast<NominalTypeDecl>(dc->getImplementedObjCContext());
if (nominal) {
// We need to add implicit initializers because they

View File

@@ -30,3 +30,12 @@
- (void)noImplMethod:(int)param;
@end
@interface NoInitImplClass: NSObject
@property (readonly, strong, nonnull) NSString *s1;
@property (strong, nonnull) NSString *s2;
@property (readonly, strong, nonnull) NSString *s3;
@property (strong, nonnull) NSString *s4;
@end

View File

@@ -1,4 +1,5 @@
// REQUIRES: rdar101420862
// Test doesn't pass on all platforms (rdar://101420862)
// REQUIRES: OS=macosx
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -I %S/Inputs/abi -F %clang-importer-sdk-path/frameworks %s -import-objc-header %S/Inputs/objc_implementation.h -emit-ir > %t.ir
// RUN: %FileCheck --input-file %t.ir %s
@@ -15,13 +16,12 @@
// CHECK: @"OBJC_METACLASS_$_ImplClass" = global %objc_class { %objc_class* @"OBJC_METACLASS_$_NSObject", %objc_class* @"OBJC_METACLASS_$_NSObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* null, {{i64 ptrtoint|%swift.opaque\* bitcast}} ({ i32, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8* }* [[_METACLASS_DATA_ImplClass:@[^, ]+]] to {{i64|%swift.opaque\*}}) }, align 8
// CHECK: [[_METACLASS_DATA_ImplClass]] = internal constant { i32, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8* } { i32 129, i32 40, i32 40, i32 0, i8* null, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.9.ImplClass, i64 0, i64 0), i8* null, i8* null, i8* null, i8* null, i8* null }, section "__DATA, __objc_const", align 8
// TODO: Why the extra i32 field above?
// CHECK: [[selector_data_init:@[^, ]+]] = private global [5 x i8] c"init\00", section "__TEXT,__objc_methname,cstring_literals", align 1
// Class
// CHECK: [[selector_data_implProperty:@[^, ]+]] = private global [13 x i8] c"implProperty\00", section "__TEXT,__objc_methname,cstring_literals", align 1
// CHECK: [[selector_data_setImplProperty_:@[^, ]+]] = private global [17 x i8] c"setImplProperty:\00", section "__TEXT,__objc_methname,cstring_literals", align 1
// CHECK: [[selector_data__cxx_destruct:@[^, ]+]] = private global [14 x i8] c".cxx_destruct\00", section "__TEXT,__objc_methname,cstring_literals", align 1
// CHECK: [[_INSTANCE_METHODS_ImplClass:@[^, ]+]] = internal constant { i32, i32, [5 x { i8*, i8*, i8* }] } { i32 24, i32 5, [5 x { i8*, i8*, i8* }] [{ i8*, i8*, i8* } { i8* getelementptr inbounds ([5 x i8], [5 x i8]* [[selector_data_init]], i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @".str.7.@16@0:8", i64 0, i64 0), i8* bitcast ({{.*}}* @"$sSo9ImplClassC19objc_implementationEABycfcTo{{(\.ptrauth)?}}" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([13 x i8], [13 x i8]* [[selector_data_implProperty]], i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @".str.7.i16@0:8", i64 0, i64 0), i8* bitcast ({{.*}}* @"$sSo9ImplClassC19objc_implementationE12implPropertys5Int32VvgTo{{(\.ptrauth)?}}" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([17 x i8], [17 x i8]* [[selector_data_setImplProperty_]], i64 0, i64 0), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @".str.10.v20@0:8i16", i64 0, i64 0), i8* bitcast ({{.*}}* @"$sSo9ImplClassC19objc_implementationE12implPropertys5Int32VvsTo{{(\.ptrauth)?}}" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([12 x i8], [12 x i8]* [[selector_data_mainMethod_]], i64 0, i64 0), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @".str.10.v20@0:8i16", i64 0, i64 0), i8* bitcast ({{.*}}* @"$sSo9ImplClassC19objc_implementationE10mainMethodyys5Int32VFTo{{(\.ptrauth)?}}" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([14 x i8], [14 x i8]* [[selector_data__cxx_destruct]], i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @".str.7.v16@0:8", i64 0, i64 0), i8* bitcast ({{.*}}* @"$sSo9ImplClassCfETo{{(\.ptrauth)?}}" to i8*) }] }, section "__DATA, __objc_data", align 8
// CHECK: [[_INSTANCE_METHODS_ImplClass:@[^, ]+]] = internal constant { i32, i32, [5 x { i8*, i8*, i8* }] } { i32 24, i32 5, [5 x { i8*, i8*, i8* }] [{ i8*, i8*, i8* } { i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"\01L_selector_data(init)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @".str.7.@16@0:8", i64 0, i64 0), i8* bitcast ({{.*}}* @"$sSo9ImplClassC19objc_implementationEABycfcTo{{(\.ptrauth)?}}" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([13 x i8], [13 x i8]* [[selector_data_implProperty]], i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @".str.7.i16@0:8", i64 0, i64 0), i8* bitcast ({{.*}}* @"$sSo9ImplClassC19objc_implementationE12implPropertys5Int32VvgTo{{(\.ptrauth)?}}" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([17 x i8], [17 x i8]* [[selector_data_setImplProperty_]], i64 0, i64 0), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @".str.10.v20@0:8i16", i64 0, i64 0), i8* bitcast ({{.*}}* @"$sSo9ImplClassC19objc_implementationE12implPropertys5Int32VvsTo{{(\.ptrauth)?}}" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([12 x i8], [12 x i8]* [[selector_data_mainMethod_]], i64 0, i64 0), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @".str.10.v20@0:8i16", i64 0, i64 0), i8* bitcast ({{.*}}* @"$sSo9ImplClassC19objc_implementationE10mainMethodyys5Int32VFTo{{(\.ptrauth)?}}" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([14 x i8], [14 x i8]* [[selector_data__cxx_destruct]], i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @".str.7.v16@0:8", i64 0, i64 0), i8* bitcast ({{.*}}* @"$sSo9ImplClassCfETo{{(\.ptrauth)?}}" to i8*) }] }, section "__DATA, __objc_data", align 8
// CHECK: [[_IVARS_ImplClass:@[^, ]+]] = internal constant { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] } { i32 32, i32 2, [2 x { i64*, i8*, i8*, i32, i32 }] [{ i64*, i8*, i8*, i32, i32 } { i64* @"$sSo9ImplClassC19objc_implementationE12implPropertys5Int32VvpWvd", i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.12.implProperty, i64 0, i64 0), i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.0., i64 0, i64 0), i32 2, i32 4 }, { i64*, i8*, i8*, i32, i32 } { i64* @"$sSo9ImplClassC19objc_implementationE13implProperty2So8NSObjectCSgvpWvd", i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.13.implProperty2, i64 0, i64 0), i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.0., i64 0, i64 0), i32 3, i32 8 }] }, section "__DATA, __objc_const", align 8
// CHECK: [[_PROPERTIES_ImplClass:@[^, ]+]] = internal constant { i32, i32, [1 x { i8*, i8* }] } { i32 16, i32 1, [1 x { i8*, i8* }] [{ i8*, i8* } { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.12.implProperty, i64 0, i64 0), i8* getelementptr inbounds ([19 x i8], [19 x i8]* @".str.18.Ti,N,VimplProperty", i64 0, i64 0) }] }, section "__DATA, __objc_const", align 8
// CHECK: [[_DATA_ImplClass:@[^, ]+]] = internal constant { i32, i32, i32, i32, i8*, i8*, { i32, i32, [5 x { i8*, i8*, i8* }] }*, i8*, { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] }*, i8*, { i32, i32, [1 x { i8*, i8* }] }* } { i32 388, i32 8, i32 24, i32 0, i8* null, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.9.ImplClass, i64 0, i64 0), { i32, i32, [5 x { i8*, i8*, i8* }] }* [[_INSTANCE_METHODS_ImplClass]], i8* null, { i32, i32, [2 x { i64*, i8*, i8*, i32, i32 }] }* [[_IVARS_ImplClass]], i8* null, { i32, i32, [1 x { i8*, i8* }] }* [[_PROPERTIES_ImplClass]] }, section "__DATA, __objc_data", align 8
@@ -66,6 +66,24 @@
}
}
//
// Second @_objcImplementation class, inherited initializer
//
// CHECK: @"OBJC_METACLASS_$_NoInitImplClass" = global %objc_class { %objc_class* @"OBJC_METACLASS_$_NSObject", %objc_class* @"OBJC_METACLASS_$_NSObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* null, i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @_METACLASS_DATA_NoInitImplClass to i64) }, align 8
// CHECK: @_METACLASS_DATA_NoInitImplClass = internal constant { i32, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8* } { i32 129, i32 40, i32 40, i32 0, i8* null, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.15.NoInitImplClass, i64 0, i64 0), i8* null, i8* null, i8* null, i8* null, i8* null }, section "__DATA, __objc_const", align 8
// CHECK: @_INSTANCE_METHODS_NoInitImplClass = internal constant { i32, i32, [8 x { i8*, i8*, i8* }] } { i32 24, i32 8, [8 x { i8*, i8*, i8* }] [{ i8*, i8*, i8* } { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @"\01L_selector_data(s1)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @".str.7.@16@0:8", i64 0, i64 0), i8* bitcast (%2* (%3*, i8*)* @"$sSo15NoInitImplClassC19objc_implementationE2s1SSvgTo" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @"\01L_selector_data(s2)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @".str.7.@16@0:8", i64 0, i64 0), i8* bitcast (%2* (%3*, i8*)* @"$sSo15NoInitImplClassC19objc_implementationE2s2SSvgTo" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([7 x i8], [7 x i8]* @"\01L_selector_data(setS2:)", i64 0, i64 0), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @".str.10.v24@0:8@16", i64 0, i64 0), i8* bitcast (void (%3*, i8*, %2*)* @"$sSo15NoInitImplClassC19objc_implementationE2s2SSvsTo" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @"\01L_selector_data(s3)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @".str.7.@16@0:8", i64 0, i64 0), i8* bitcast (%2* (%3*, i8*)* @"$sSo15NoInitImplClassC19objc_implementationE2s3SSvgTo" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @"\01L_selector_data(s4)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @".str.7.@16@0:8", i64 0, i64 0), i8* bitcast (%2* (%3*, i8*)* @"$sSo15NoInitImplClassC19objc_implementationE2s4SSvgTo" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([7 x i8], [7 x i8]* @"\01L_selector_data(setS4:)", i64 0, i64 0), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @".str.10.v24@0:8@16", i64 0, i64 0), i8* bitcast (void (%3*, i8*, %2*)* @"$sSo15NoInitImplClassC19objc_implementationE2s4SSvsTo" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"\01L_selector_data(init)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @".str.7.@16@0:8", i64 0, i64 0), i8* bitcast (%3* (%3*, i8*)* @"$sSo15NoInitImplClassC19objc_implementationEABycfcTo" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([14 x i8], [14 x i8]* @"\01L_selector_data(.cxx_destruct)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @".str.7.v16@0:8", i64 0, i64 0), i8* bitcast (void (%3*, i8*)* @"$sSo15NoInitImplClassCfETo" to i8*) }] }, section "__DATA, __objc_data", align 8
// CHECK: @_IVARS_NoInitImplClass = internal constant { i32, i32, [4 x { i64*, i8*, i8*, i32, i32 }] } { i32 32, i32 4, [4 x { i64*, i8*, i8*, i32, i32 }] [{ i64*, i8*, i8*, i32, i32 } { i64* @"$sSo15NoInitImplClassC19objc_implementationE2s1SSvpWvd", i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2.s1, i64 0, i64 0), i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.0., i64 0, i64 0), i32 3, i32 16 }, { i64*, i8*, i8*, i32, i32 } { i64* @"$sSo15NoInitImplClassC19objc_implementationE2s2SSvpWvd", i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2.s2, i64 0, i64 0), i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.0., i64 0, i64 0), i32 3, i32 16 }, { i64*, i8*, i8*, i32, i32 } { i64* @"$sSo15NoInitImplClassC19objc_implementationE2s3SSvpWvd", i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2.s3, i64 0, i64 0), i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.0., i64 0, i64 0), i32 3, i32 16 }, { i64*, i8*, i8*, i32, i32 } { i64* @"$sSo15NoInitImplClassC19objc_implementationE2s4SSvpWvd", i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2.s4, i64 0, i64 0), i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.0., i64 0, i64 0), i32 3, i32 16 }] }, section "__DATA, __objc_const", align 8
// CHECK: @_PROPERTIES_NoInitImplClass = internal constant { i32, i32, [4 x { i8*, i8* }] } { i32 16, i32 4, [4 x { i8*, i8* }] [{ i8*, i8* } { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2.s1, i64 0, i64 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @".str.16.T@\22NSString\22,N,R", i64 0, i64 0) }, { i8*, i8* } { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2.s2, i64 0, i64 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @".str.16.T@\22NSString\22,N,C", i64 0, i64 0) }, { i8*, i8* } { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2.s3, i64 0, i64 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @".str.16.T@\22NSString\22,N,R", i64 0, i64 0) }, { i8*, i8* } { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2.s4, i64 0, i64 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @".str.16.T@\22NSString\22,N,C", i64 0, i64 0) }] }, section "__DATA, __objc_const", align 8
// CHECK: @_DATA_NoInitImplClass = internal constant { i32, i32, i32, i32, i8*, i8*, { i32, i32, [8 x { i8*, i8*, i8* }] }*, i8*, { i32, i32, [4 x { i64*, i8*, i8*, i32, i32 }] }*, i8*, { i32, i32, [4 x { i8*, i8* }] }* } { i32 388, i32 8, i32 72, i32 0, i8* null, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.15.NoInitImplClass, i64 0, i64 0), { i32, i32, [8 x { i8*, i8*, i8* }] }* @_INSTANCE_METHODS_NoInitImplClass, i8* null, { i32, i32, [4 x { i64*, i8*, i8*, i32, i32 }] }* @_IVARS_NoInitImplClass, i8* null, { i32, i32, [4 x { i8*, i8* }] }* @_PROPERTIES_NoInitImplClass }, section "__DATA, __objc_data", align 8
// CHECK: @"OBJC_CLASS_$_NoInitImplClass" = global <{ i64, %objc_class*, %swift.opaque*, %swift.opaque*, { i32, i32, i32, i32, i8*, i8*, { i32, i32, [8 x { i8*, i8*, i8* }] }*, i8*, { i32, i32, [4 x { i64*, i8*, i8*, i32, i32 }] }*, i8*, { i32, i32, [4 x { i8*, i8* }] }* }* }> <{ i64 ptrtoint (%objc_class* @"OBJC_METACLASS_$_NoInitImplClass" to i64), %objc_class* @"OBJC_CLASS_$_NSObject", %swift.opaque* @_objc_empty_cache, %swift.opaque* null, { i32, i32, i32, i32, i8*, i8*, { i32, i32, [8 x { i8*, i8*, i8* }] }*, i8*, { i32, i32, [4 x { i64*, i8*, i8*, i32, i32 }] }*, i8*, { i32, i32, [4 x { i8*, i8* }] }* }* @_DATA_NoInitImplClass }>, section "__DATA,__objc_data, regular", align 8
@_objcImplementation extension NoInitImplClass {
@objc let s1 = "s1v"
@objc var s2 = "s2v"
@objc(s3) let s3 = "s3v"
@objc(s4) var s4 = "s4v"
}
//
// @objc subclass of @_objcImplementation class
//
@@ -75,7 +93,7 @@
// CHECK: [[_METACLASS_DATA_SwiftSubclass]] = internal constant { i32, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8* } { i32 129, i32 40, i32 40, i32 0, i8* null, i8* getelementptr inbounds ([41 x i8], [41 x i8]* @.str.40._TtC19objc_implementation13SwiftSubclass, i64 0, i64 0), i8* null, i8* null, i8* null, i8* null, i8* null }, section "__DATA, __objc_const", align 8
// Class
// CHECK: [[_INSTANCE_METHODS_SwiftSubclass:@[^, ]+]] = internal constant { i32, i32, [2 x { i8*, i8*, i8* }] } { i32 24, i32 2, [2 x { i8*, i8*, i8* }] [{ i8*, i8*, i8* } { i8* getelementptr inbounds ([12 x i8], [12 x i8]* [[selector_data_mainMethod_]], i64 0, i64 0), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @".str.10.v20@0:8i16", i64 0, i64 0), i8* bitcast ({{.*}}* @"$s19objc_implementation13SwiftSubclassC10mainMethodyys5Int32VFTo{{(\.ptrauth)?}}" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([5 x i8], [5 x i8]* [[selector_data_init]], i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @".str.7.@16@0:8", i64 0, i64 0), i8* bitcast ({{.*}}* @"$s19objc_implementation13SwiftSubclassCACycfcTo{{(\.ptrauth)?}}" to i8*) }] }, section "__DATA, __objc_data", align 8
// CHECK: [[_INSTANCE_METHODS_SwiftSubclass:@[^, ]+]] = internal constant { i32, i32, [2 x { i8*, i8*, i8* }] } { i32 24, i32 2, [2 x { i8*, i8*, i8* }] [{ i8*, i8*, i8* } { i8* getelementptr inbounds ([12 x i8], [12 x i8]* [[selector_data_mainMethod_]], i64 0, i64 0), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @".str.10.v20@0:8i16", i64 0, i64 0), i8* bitcast ({{.*}}* @"$s19objc_implementation13SwiftSubclassC10mainMethodyys5Int32VFTo{{(\.ptrauth)?}}" to i8*) }, { i8*, i8*, i8* } { i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"\01L_selector_data(init)", i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @".str.7.@16@0:8", i64 0, i64 0), i8* bitcast ({{.*}}* @"$s19objc_implementation13SwiftSubclassCACycfcTo{{(\.ptrauth)?}}" to i8*) }] }, section "__DATA, __objc_data", align 8
// CHECK: [[_DATA_SwiftSubclass:@[^, ]+]] = internal constant { i32, i32, i32, i32, i8*, i8*, { i32, i32, [2 x { i8*, i8*, i8* }] }*, i8*, i8*, i8*, i8* } { i32 128, i32 24, i32 24, i32 0, i8* null, i8* getelementptr inbounds ([41 x i8], [41 x i8]* @.str.40._TtC19objc_implementation13SwiftSubclass, i64 0, i64 0), { i32, i32, [2 x { i8*, i8*, i8* }] }* [[_INSTANCE_METHODS_SwiftSubclass]], i8* null, i8* null, i8* null, i8* null }, section "__DATA, __objc_data", align 8
// Swift metadata
@@ -172,6 +190,18 @@ public func fn(impl: ImplClass, swiftSub: SwiftSubclass) {
// ObjC calling convention -[ImplClass(Category1) category1Method:]
// CHECK-LABEL: define internal void @"$sSo9ImplClassC19objc_implementationE15category1Methodyys5Int32VFTo"
// Swift calling convention -[NoInitImplClass init]
// CHECK-LABEL: define swiftcc %TSo15NoInitImplClassC* @"$sSo15NoInitImplClassC19objc_implementationEABycfc"
// CHECK-DAG: load i64, i64* @"$sSo15NoInitImplClassC19objc_implementationE2s1SSvpWvd", align 8
// CHECK-DAG: load i64, i64* @"$sSo15NoInitImplClassC19objc_implementationE2s2SSvpWvd", align 8
// CHECK-DAG: load i64, i64* @"$sSo15NoInitImplClassC19objc_implementationE2s3SSvpWvd", align 8
// CHECK-DAG: load i64, i64* @"$sSo15NoInitImplClassC19objc_implementationE2s4SSvpWvd", align 8
// CHECK: [[SEL_init:%[^ ]+]] = load i8*, i8** @"\01L_selector(init)", align 8
// CHECK: call %0* bitcast (void ()* @objc_msgSendSuper{{.*}} [[SEL_init]])
// ObjC calling convention -[NoInitImplClass init]
// CHECK-LABEL: define internal %3* @"$sSo15NoInitImplClassC19objc_implementationEABycfcTo"
// Swift calling convention SwiftSubclass.mainMethod(_:)
// CHECK-LABEL: define swiftcc void @"$s19objc_implementation13SwiftSubclassC10mainMethodyys5Int32VF"
@@ -187,8 +217,8 @@ public func fn(impl: ImplClass, swiftSub: SwiftSubclass) {
// CHECK: [[PARAM_impl:%[^ ]+]] = bitcast %TSo9ImplClassC* %0 to %1*
// CHECK: call void bitcast (void ()* @objc_msgSend to void (%1*, i8*, i32)*)(%1* [[PARAM_impl]], i8* [[SEL_1]], i32 0)
// CHECK: [[SEL_2:%[^ ]+]] = load i8*, i8** @"\01L_selector(mainMethod:)", align 8
// CHECK: [[PARAM_swiftSub:%[^ ]+]] = bitcast %T19objc_implementation13SwiftSubclassC* %1 to %2*
// CHECK: call void bitcast (void ()* @objc_msgSend to void (%2*, i8*, i32)*)(%2* [[PARAM_swiftSub]], i8* [[SEL_2]], i32 1)
// CHECK: [[PARAM_swiftSub:%[^ ]+]] = bitcast %T19objc_implementation13SwiftSubclassC* %1 to [[SEL_1]]*
// CHECK: call void bitcast (void ()* @objc_msgSend to void ([[SEL_1]]*, i8*, i32)*)([[SEL_1]]* [[PARAM_swiftSub]], i8* [[SEL_2]], i32 1)
// CHECK: ret void
// CHECK: }

View File

@@ -1,4 +1,5 @@
// REQUIRES: rdar101543397
// Test doesn't pass on all platforms (rdar://101543397)
// REQUIRES: OS=macosx
//
// Build objc_implementation.framework