Skip to content

Commit 7d93b75

Browse files
authored
Merge pull request #63534 from beccadax/default-is-not-init-stars
Make objcImpl classes derive inherited inits
2 parents 9401926 + 31d8cad commit 7d93b75

File tree

6 files changed

+78
-23
lines changed

6 files changed

+78
-23
lines changed

lib/SILGen/SILGenConstructor.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,8 @@ emitMemberInit(SILGenFunction &SGF, VarDecl *selfDecl, Pattern *pattern) {
10681068
slot = SGF.B.createStructElementAddr(pattern, self.forward(SGF), field,
10691069
fieldTy.getAddressType());
10701070
} else {
1071-
assert(isa<ClassDecl>(field->getDeclContext()));
1071+
assert(isa<ClassDecl>(field->getDeclContext()->
1072+
getImplementedObjCContext()));
10721073
slot = SGF.B.createRefElementAddr(pattern, self.forward(SGF), field,
10731074
fieldTy.getAddressType());
10741075
}
@@ -1165,7 +1166,7 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
11651166
NominalTypeDecl *nominal) {
11661167
auto subs = getSubstitutionsForPropertyInitializer(dc, nominal);
11671168

1168-
for (auto member : nominal->getMembers()) {
1169+
for (auto member : nominal->getImplementationContext()->getMembers()) {
11691170
// Find instance pattern binding declarations that have initializers.
11701171
if (auto pbd = dyn_cast<PatternBindingDecl>(member)) {
11711172
if (pbd->isStatic()) continue;

lib/Sema/CodeSynthesis.cpp

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -468,12 +468,26 @@ createDesignatedInitOverrideGenericParams(ASTContext &ctx,
468468
ArrayRef<RequirementRepr>(), SourceLoc());
469469
}
470470

471+
/// True if the type has an opaque clang implementation, meaning it is imported
472+
/// and doesn't have an \c \@objcImplementation extension.
473+
static bool hasClangImplementation(const NominalTypeDecl *decl) {
474+
return decl->hasClangNode() && !decl->getObjCImplementationDecl();
475+
}
476+
477+
/// True if \p member is in the main body of \p ty, where the "main body" is
478+
/// either the type itself (the usual case) or its \c \@objcImplementation
479+
/// extension (if one is present).
480+
static bool isInMainBody(ValueDecl *member, NominalTypeDecl *ty) {
481+
return member->getDeclContext() ==
482+
ty->getImplementationContext()->getAsGenericContext();
483+
}
484+
471485
static void
472486
configureInheritedDesignatedInitAttributes(ClassDecl *classDecl,
473487
ConstructorDecl *ctor,
474488
ConstructorDecl *superclassCtor,
475489
ASTContext &ctx) {
476-
assert(ctor->getDeclContext() == classDecl);
490+
assert(isInMainBody(ctor, classDecl));
477491

478492
AccessLevel access = classDecl->getFormalAccess();
479493
access = std::max(access, AccessLevel::Internal);
@@ -705,6 +719,7 @@ createDesignatedInitOverride(ClassDecl *classDecl,
705719

706720
// Create the initializer declaration, inheriting the name,
707721
// failability, and throws from the superclass initializer.
722+
auto implCtx = classDecl->getImplementationContext()->getAsGenericContext();
708723
auto ctor =
709724
new (ctx) ConstructorDecl(superclassCtor->getName(),
710725
classDecl->getBraces().Start,
@@ -714,8 +729,7 @@ createDesignatedInitOverride(ClassDecl *classDecl,
714729
/*AsyncLoc=*/SourceLoc(),
715730
/*Throws=*/superclassCtor->hasThrows(),
716731
/*ThrowsLoc=*/SourceLoc(),
717-
bodyParams, genericParams,
718-
classDecl);
732+
bodyParams, genericParams, implCtx);
719733

720734
ctor->setImplicit();
721735

@@ -837,9 +851,9 @@ static void diagnoseMissingRequiredInitializer(
837851

838852
bool AreAllStoredPropertiesDefaultInitableRequest::evaluate(
839853
Evaluator &evaluator, NominalTypeDecl *decl) const {
840-
assert(!decl->hasClangNode());
854+
assert(!hasClangImplementation(decl));
841855

842-
for (auto member : decl->getMembers()) {
856+
for (auto member : decl->getImplementationContext()->getMembers()) {
843857
// If a stored property lacks an initial value and if there is no way to
844858
// synthesize an initial value (e.g. for an optional) then we suppress
845859
// generation of the default initializer.
@@ -880,7 +894,7 @@ bool AreAllStoredPropertiesDefaultInitableRequest::evaluate(
880894

881895
static bool areAllStoredPropertiesDefaultInitializable(Evaluator &eval,
882896
NominalTypeDecl *decl) {
883-
if (decl->hasClangNode())
897+
if (hasClangImplementation(decl))
884898
return true;
885899

886900
return evaluateOrDefault(
@@ -890,11 +904,11 @@ static bool areAllStoredPropertiesDefaultInitializable(Evaluator &eval,
890904
bool
891905
HasUserDefinedDesignatedInitRequest::evaluate(Evaluator &evaluator,
892906
NominalTypeDecl *decl) const {
893-
assert(!decl->hasClangNode());
907+
assert(!hasClangImplementation(decl));
894908

895909
auto results = decl->lookupDirect(DeclBaseName::createConstructor());
896910
for (auto *member : results) {
897-
if (isa<ExtensionDecl>(member->getDeclContext()))
911+
if (!isInMainBody(member, decl))
898912
continue;
899913

900914
auto *ctor = cast<ConstructorDecl>(member);
@@ -908,7 +922,7 @@ HasUserDefinedDesignatedInitRequest::evaluate(Evaluator &evaluator,
908922
static bool hasUserDefinedDesignatedInit(Evaluator &eval,
909923
NominalTypeDecl *decl) {
910924
// Imported decls don't have a designated initializer defined by the user.
911-
if (decl->hasClangNode())
925+
if (hasClangImplementation(decl))
912926
return false;
913927

914928
return evaluateOrDefault(eval, HasUserDefinedDesignatedInitRequest{decl},
@@ -935,7 +949,7 @@ static void collectNonOveriddenSuperclassInits(
935949

936950
auto ctors = subclass->lookupDirect(DeclBaseName::createConstructor());
937951
for (auto *member : ctors) {
938-
if (isa<ExtensionDecl>(member->getDeclContext()))
952+
if (!isInMainBody(member, subclass))
939953
continue;
940954

941955
auto *ctor = cast<ConstructorDecl>(member);
@@ -1038,7 +1052,7 @@ static void addImplicitInheritedConstructorsToClass(ClassDecl *decl) {
10381052

10391053
auto results = decl->lookupDirect(DeclBaseName::createConstructor());
10401054
for (auto *member : results) {
1041-
if (isa<ExtensionDecl>(member->getDeclContext()))
1055+
if (!isInMainBody(member, decl))
10421056
continue;
10431057

10441058
auto *ctor = cast<ConstructorDecl>(member);
@@ -1066,7 +1080,7 @@ static void addImplicitInheritedConstructorsToClass(ClassDecl *decl) {
10661080

10671081
if (auto ctor = createDesignatedInitOverride(
10681082
decl, superclassCtor, kind, ctx)) {
1069-
decl->addMember(ctor);
1083+
decl->getImplementationContext()->addMember(ctor);
10701084
}
10711085
}
10721086
}
@@ -1107,7 +1121,7 @@ InheritsSuperclassInitializersRequest::evaluate(Evaluator &eval,
11071121

11081122
static bool shouldAttemptInitializerSynthesis(const NominalTypeDecl *decl) {
11091123
// Don't synthesize initializers for imported decls.
1110-
if (decl->hasClangNode())
1124+
if (hasClangImplementation(decl))
11111125
return false;
11121126

11131127
// Don't add implicit constructors in module interfaces.

lib/Sema/TypeCheckDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2737,7 +2737,7 @@ static ArrayRef<Decl *> evaluateMembersRequest(
27372737
return ctx.AllocateCopy(result);
27382738
}
27392739

2740-
auto nominal = dyn_cast<NominalTypeDecl>(idc);
2740+
auto nominal = dyn_cast<NominalTypeDecl>(dc->getImplementedObjCContext());
27412741

27422742
if (nominal) {
27432743
// We need to add implicit initializers because they

test/IRGen/Inputs/objc_implementation.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,12 @@
3030
- (void)noImplMethod:(int)param;
3131

3232
@end
33+
34+
@interface NoInitImplClass: NSObject
35+
36+
@property (readonly, strong, nonnull) NSString *s1;
37+
@property (strong, nonnull) NSString *s2;
38+
@property (readonly, strong, nonnull) NSString *s3;
39+
@property (strong, nonnull) NSString *s4;
40+
41+
@end

0 commit comments

Comments
 (0)