diff --git a/lib/ClangImporter/ClangAdapter.cpp b/lib/ClangImporter/ClangAdapter.cpp index 6260ccdb911a8..582d244e865e2 100644 --- a/lib/ClangImporter/ClangAdapter.cpp +++ b/lib/ClangImporter/ClangAdapter.cpp @@ -601,29 +601,6 @@ OptionalTypeKind importer::translateNullability(clang::NullabilityKind kind) { llvm_unreachable("Invalid NullabilityKind."); } -bool importer::hasDesignatedInitializers( - const clang::ObjCInterfaceDecl *classDecl) { - if (classDecl->hasDesignatedInitializers()) - return true; - - return false; -} - -bool importer::isDesignatedInitializer( - const clang::ObjCInterfaceDecl *classDecl, - const clang::ObjCMethodDecl *method) { - // If the information is on the AST, use it. - if (classDecl->hasDesignatedInitializers()) { - auto *methodParent = method->getClassInterface(); - if (!methodParent || - methodParent->getCanonicalDecl() == classDecl->getCanonicalDecl()) { - return method->hasAttr(); - } - } - - return false; -} - bool importer::isRequiredInitializer(const clang::ObjCMethodDecl *method) { // FIXME: No way to express this in Objective-C. return false; diff --git a/lib/ClangImporter/ClangAdapter.h b/lib/ClangImporter/ClangAdapter.h index 84c35ad118961..47a20d202b89d 100644 --- a/lib/ClangImporter/ClangAdapter.h +++ b/lib/ClangImporter/ClangAdapter.h @@ -111,15 +111,6 @@ bool hasNativeSwiftDecl(const clang::Decl *decl); /// Translation API nullability from an API note into an optional kind. OptionalTypeKind translateNullability(clang::NullabilityKind kind); -/// Determine whether the given class has designated initializers, -/// consulting -bool hasDesignatedInitializers(const clang::ObjCInterfaceDecl *classDecl); - -/// Determine whether the given method is a designated initializer -/// of the given class. -bool isDesignatedInitializer(const clang::ObjCInterfaceDecl *classDecl, - const clang::ObjCMethodDecl *method); - /// Determine whether the given method is a required initializer /// of the given class. bool isRequiredInitializer(const clang::ObjCMethodDecl *method); diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 524f7055b0a24..4791f3afec87c 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -4415,7 +4415,7 @@ namespace { ConstructorDecl *importConstructor(const clang::ObjCMethodDecl *objcMethod, DeclContext *dc, bool implicit, - Optional kindIn, + CtorInitializerKind kind, bool required, ObjCSelector selector, ImportedName importedName, @@ -6035,9 +6035,10 @@ ConstructorDecl *SwiftDeclConverter::importConstructor( } bool redundant; - auto result = - importConstructor(objcMethod, dc, implicit, kind, required, selector, - importedName, params, variadic, redundant); + auto result = importConstructor(objcMethod, dc, implicit, + kind.getValueOr(importedName.getInitKind()), + required, selector, importedName, params, + variadic, redundant); // If this is a compatibility stub, mark it as such. if (result && correctSwiftName) @@ -6147,7 +6148,7 @@ bool SwiftDeclConverter::existingConstructorIsWorse( /// constructor declaration appropriately. ConstructorDecl *SwiftDeclConverter::importConstructor( const clang::ObjCMethodDecl *objcMethod, DeclContext *dc, bool implicit, - Optional kindIn, bool required, ObjCSelector selector, + CtorInitializerKind kind, bool required, ObjCSelector selector, ImportedName importedName, ArrayRef args, bool variadic, bool &redundant) { redundant = false; @@ -6156,35 +6157,6 @@ ConstructorDecl *SwiftDeclConverter::importConstructor( auto ownerNominal = dc->getSelfNominalTypeDecl(); assert(ownerNominal && "Method in non-type context?"); - // Find the interface, if we can. - const clang::ObjCInterfaceDecl *interface = nullptr; - if (auto classDecl = dyn_cast(ownerNominal)) { - interface = - dyn_cast_or_null(classDecl->getClangDecl()); - } - - // If we weren't told what kind of initializer this should be, - // figure it out now. - CtorInitializerKind kind; - - if (kindIn) { - kind = *kindIn; - - // If we know this is a designated initializer, mark it as such. - if (interface && hasDesignatedInitializers(interface) && - isDesignatedInitializer(interface, objcMethod)) - kind = CtorInitializerKind::Designated; - } else { - // If the owning Objective-C class has designated initializers and this - // is not one of them, treat it as a convenience initializer. - if (interface && hasDesignatedInitializers(interface) && - !isDesignatedInitializer(interface, objcMethod)) { - kind = CtorInitializerKind::Convenience; - } else { - kind = CtorInitializerKind::Designated; - } - } - // Import the type that this method will have. Optional errorConvention; ParameterList *bodyParams; @@ -7228,9 +7200,9 @@ void SwiftDeclConverter::importInheritedConstructors( }; // The kind of initializer to import. If this class has designated - // initializers, everything it imports is a convenience initializer. + // initializers, everything it inherits is a convenience initializer. Optional kind; - if (hasDesignatedInitializers(curObjCClass)) + if (curObjCClass->hasDesignatedInitializers()) kind = CtorInitializerKind::Convenience; diff --git a/lib/ClangImporter/ImportName.cpp b/lib/ClangImporter/ImportName.cpp index dc1b4d9a9af74..c2494397d8a37 100644 --- a/lib/ClangImporter/ImportName.cpp +++ b/lib/ClangImporter/ImportName.cpp @@ -740,9 +740,7 @@ getFactoryAsInit(const clang::ObjCInterfaceDecl *classDecl, /// should be stripped from the first selector piece, e.g., "init" /// or the restated name of the class in a factory method. /// -/// \param kind Will be set to the kind of initializer being -/// imported. Note that this does not distinguish designated -/// vs. convenience; both will be classified as "designated". +/// \param kind Will be set to the kind of initializer being imported. static bool shouldImportAsInitializer(const clang::ObjCMethodDecl *method, ImportNameVersion version, unsigned &prefixLength, @@ -750,7 +748,17 @@ static bool shouldImportAsInitializer(const clang::ObjCMethodDecl *method, /// Is this an initializer? if (isInitMethod(method)) { prefixLength = 4; - kind = CtorInitializerKind::Designated; + + // If the owning Objective-C class has designated initializers and this + // is not one of them, treat it as a convenience initializer. + const clang::ObjCInterfaceDecl *interface = method->getClassInterface(); + if (interface && interface->hasDesignatedInitializers() && + !method->hasAttr()) { + kind = CtorInitializerKind::Convenience; + } else { + kind = CtorInitializerKind::Designated; + } + return true; }