@@ -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+
471485static void
472486configureInheritedDesignatedInitAttributes (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
838852bool 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
881895static 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,
890904bool
891905HasUserDefinedDesignatedInitRequest::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,
908922static 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
11081122static 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.
0 commit comments