diff --git a/include/swift/ClangImporter/ClangImporter.h b/include/swift/ClangImporter/ClangImporter.h index 242f0750d432a..c0881c9c9294f 100644 --- a/include/swift/ClangImporter/ClangImporter.h +++ b/include/swift/ClangImporter/ClangImporter.h @@ -260,8 +260,7 @@ class ClangImporter final : public ClangModuleLoader { /// The return value may be an empty identifier, in which case the enum would /// not be imported. /// - /// This is mostly an implementation detail of the importer, but is also - /// used by the debugger. + /// This is not used by the importer itself, but is used by the debugger. Identifier getEnumConstantName(const clang::EnumConstantDecl *enumConstant); /// Writes the mangled name of \p clangDecl to \p os. diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index bcacb55497a90..01fa9e0ab4a61 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -2041,10 +2041,11 @@ namespace { decl->setImplicit(); } - /// Create a typealias for the Swift 2 name of a Clang type declaration. - Decl *importSwift2TypeAlias(const clang::NamedDecl *decl, - ImportedName swift2Name, - ImportedName correctSwiftName); + /// Create a typealias for the name of a Clang type declaration in an + /// alternate version of Swift. + Decl *importCompatibilityTypeAlias(const clang::NamedDecl *decl, + ImportedName compatibilityName, + ImportedName correctSwiftName); /// Create a swift_newtype struct corresponding to a typedef. Returns /// nullptr if unable. @@ -2062,7 +2063,8 @@ namespace { // If we've been asked to produce a Swift 2 stub, handle it via a // typealias. if (correctSwiftName) - return importSwift2TypeAlias(Decl, importedName, *correctSwiftName); + return importCompatibilityTypeAlias(Decl, importedName, + *correctSwiftName); Type SwiftType; if (Decl->getDeclContext()->getRedeclContext()->isTranslationUnit()) { @@ -2277,7 +2279,8 @@ namespace { // If we've been asked to produce a Swift 2 stub, handle it via a // typealias. if (correctSwiftName) - return importSwift2TypeAlias(decl, importedName, *correctSwiftName); + return importCompatibilityTypeAlias(decl, importedName, + *correctSwiftName); auto dc = Impl.importDeclContextOf(decl, importedName.getEffectiveContext()); @@ -2693,7 +2696,8 @@ namespace { // If we've been asked to produce a Swift 2 stub, handle it via a // typealias. if (correctSwiftName) - return importSwift2TypeAlias(decl, importedName, *correctSwiftName); + return importCompatibilityTypeAlias(decl, importedName, + *correctSwiftName); auto dc = Impl.importDeclContextOf(decl, importedName.getEffectiveContext()); @@ -3957,7 +3961,8 @@ namespace { // If we've been asked to produce a Swift 2 stub, handle it via a // typealias. if (correctSwiftName) - return importSwift2TypeAlias(decl, importedName, *correctSwiftName); + return importCompatibilityTypeAlias(decl, importedName, + *correctSwiftName); Identifier name = importedName.getDeclName().getBaseName(); @@ -4092,7 +4097,8 @@ namespace { // If we've been asked to produce a Swift 2 stub, handle it via a // typealias. if (correctSwiftName) - return importSwift2TypeAlias(decl, importedName, *correctSwiftName); + return importCompatibilityTypeAlias(decl, importedName, + *correctSwiftName); auto name = importedName.getDeclName().getBaseName(); @@ -4630,9 +4636,10 @@ SwiftDeclConverter::importCFClassType(const clang::TypedefNameDecl *decl, return theClass; } -Decl *SwiftDeclConverter::importSwift2TypeAlias(const clang::NamedDecl *decl, - ImportedName swift2Name, - ImportedName correctSwiftName) { +Decl *SwiftDeclConverter::importCompatibilityTypeAlias( + const clang::NamedDecl *decl, + ImportedName compatibilityName, + ImportedName correctSwiftName) { // Import the referenced declaration. If it doesn't come in as a type, // we don't care. auto importedDecl = Impl.importDecl(decl, getActiveSwiftVersion()); @@ -4665,19 +4672,14 @@ Decl *SwiftDeclConverter::importSwift2TypeAlias(const clang::NamedDecl *decl, // Create the type alias. auto alias = Impl.createDeclWithClangNode( - decl, - Accessibility::Public, Impl.importSourceLoc(decl->getLocStart()), - SourceLoc(), swift2Name.getDeclName().getBaseName(), - Impl.importSourceLoc(decl->getLocation()), - genericParams, dc); + decl, Accessibility::Public, Impl.importSourceLoc(decl->getLocStart()), + SourceLoc(), compatibilityName.getDeclName().getBaseName(), + Impl.importSourceLoc(decl->getLocation()), genericParams, dc); alias->setUnderlyingType(underlyingType); alias->setGenericEnvironment(genericEnv); - // Record that this is the Swift 2 version of this declaration. - Impl.ImportedDecls[{decl->getCanonicalDecl(), ImportNameVersion::Swift2}] = - alias; - - // Mark it as the Swift 2 variant. + // Record that this is the official version of this declaration. + Impl.ImportedDecls[{decl->getCanonicalDecl(), getVersion()}] = alias; markAsVariant(alias, correctSwiftName); return alias; } @@ -6516,7 +6518,7 @@ getSwiftNameFromClangName(StringRef replacement) { if (!clangDecl) return ""; - auto importedName = importFullName(clangDecl, ImportNameVersion::Swift3); + auto importedName = importFullName(clangDecl, CurrentVersion); if (!importedName) return ""; @@ -6758,7 +6760,7 @@ ClangImporter::Implementation::importDeclImpl(const clang::NamedDecl *ClangDecl, Result = converter.Visit(ClangDecl); HadForwardDeclaration = converter.hadForwardDeclaration(); } - if (!Result && version > ImportNameVersion::Swift2) { + if (!Result && version == CurrentVersion) { // If we couldn't import this Objective-C entity, determine // whether it was a required member of a protocol. bool hasMissingRequiredMember = false; @@ -7568,7 +7570,7 @@ ClangImporter::Implementation::getSpecialTypedefKind(clang::TypedefNameDecl *dec Identifier ClangImporter::getEnumConstantName(const clang::EnumConstantDecl *enumConstant){ - return Impl.importFullName(enumConstant, ImportNameVersion::Swift3) + return Impl.importFullName(enumConstant, Impl.CurrentVersion) .getDeclName() .getBaseName(); } diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp index 841c171a98bb7..36e4dfa5d9196 100644 --- a/lib/ClangImporter/ImportType.cpp +++ b/lib/ClangImporter/ImportType.cpp @@ -1626,7 +1626,7 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList( } // Figure out the name for this parameter. - Identifier bodyName = importFullName(param, ImportNameVersion::Swift3) + Identifier bodyName = importFullName(param, CurrentVersion) .getDeclName() .getBaseName(); @@ -2037,7 +2037,7 @@ Type ClangImporter::Implementation::importMethodType( } // Figure out the name for this parameter. - Identifier bodyName = importFullName(param, ImportNameVersion::Swift3) + Identifier bodyName = importFullName(param, CurrentVersion) .getDeclName() .getBaseName(); @@ -2194,7 +2194,7 @@ Type ClangImporter::Implementation::importAccessorMethodType( } else { const clang::ParmVarDecl *param = clangDecl->parameters().front(); - ImportedName fullBodyName = importFullName(param,ImportNameVersion::Swift3); + ImportedName fullBodyName = importFullName(param, CurrentVersion); Identifier bodyName = fullBodyName.getDeclName().getBaseName(); SourceLoc nameLoc = importSourceLoc(param->getLocation()); Identifier argLabel = functionName.getDeclName().getArgumentNames().front(); diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes index 747e0bb9ed663..3cff8ce99f7bd 100644 --- a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes +++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes @@ -79,7 +79,16 @@ SwiftVersions: - Name: accessorsOnlyRenamedRetypedClass PropertyKind: Class SwiftImportAsAccessors: true + Protocols: + - Name: ProtoWithVersionedUnavailableMember + Methods: + - Selector: requirement + MethodKind: Instance + ResultType: 'ForwardClass * _Nullable' Functions: - Name: acceptDoublePointer SwiftName: 'acceptPointer(_:)' Nullability: [ O ] + Tags: + - Name: SomeCStruct + SwiftName: ImportantCStruct diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h index b0a6023e0c4b9..06e48f9b8c73a 100644 --- a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h +++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h @@ -2,6 +2,8 @@ void jumpToLocation(double x, double y, double z); void acceptDoublePointer(double* _Nonnull ptr) __attribute__((swift_name("accept(_:)"))); +void oldAcceptDoublePointer(double* _Nonnull ptr) __attribute__((availability(swift, unavailable, replacement="acceptDoublePointer"))); + #ifdef __OBJC__ __attribute__((objc_root_class)) @@ -13,5 +15,8 @@ __attribute__((objc_root_class)) -(nonnull id)methodWithA:(nonnull id)a; @end +#endif // __OBJC__ + #import -#endif +#import +#import diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Properties.h b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Properties.h index 93ab5b0881001..9d21bde29f5e7 100644 --- a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Properties.h +++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Properties.h @@ -1,3 +1,4 @@ +#ifdef __OBJC__ #pragma clang assume_nonnull begin __attribute__((objc_root_class)) @@ -33,3 +34,4 @@ __attribute__((objc_root_class)) @end #pragma clang assume_nonnull end +#endif // __OBJC__ diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Protocols.h b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Protocols.h new file mode 100644 index 0000000000000..6a8840c019d29 --- /dev/null +++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Protocols.h @@ -0,0 +1,11 @@ +#ifdef __OBJC__ +#pragma clang assume_nonnull begin + +@class ForwardClass; // used by API notes + +@protocol ProtoWithVersionedUnavailableMember +- (nullable id)requirement; +@end + +#pragma clang assume_nonnull end +#endif // __OBJC__ diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Types.h b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Types.h new file mode 100644 index 0000000000000..c44439fd74fd3 --- /dev/null +++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Types.h @@ -0,0 +1,7 @@ +#pragma clang assume_nonnull begin + +struct __attribute__((swift_name("VeryImportantCStruct"))) SomeCStruct { + int field; +}; + +#pragma clang assume_nonnull end diff --git a/test/APINotes/versioned-objc.swift b/test/APINotes/versioned-objc.swift new file mode 100644 index 0000000000000..4ff367c156f6d --- /dev/null +++ b/test/APINotes/versioned-objc.swift @@ -0,0 +1,16 @@ +// RUN: rm -rf %t && mkdir -p %t + +// RUN: not %target-swift-frontend -typecheck -F %S/Inputs/custom-frameworks -swift-version 4 %s 2>&1 | %FileCheck -check-prefix=CHECK-DIAGS -check-prefix=CHECK-DIAGS-4 %s +// RUN: not %target-swift-frontend -typecheck -F %S/Inputs/custom-frameworks -swift-version 3 %s 2>&1 | %FileCheck -check-prefix=CHECK-DIAGS -check-prefix=CHECK-DIAGS-3 %s + +// REQUIRES: objc_interop + +import APINotesFrameworkTest + +// CHECK-DIAGS-4-NOT: versioned-objc.swift:[[@LINE-1]]: +class ProtoWithVersionedUnavailableMemberImpl: ProtoWithVersionedUnavailableMember { + // CHECK-DIAGS-3: versioned-objc.swift:[[@LINE-1]]:7: error: type 'ProtoWithVersionedUnavailableMemberImpl' cannot conform to protocol 'ProtoWithVersionedUnavailableMember' because it has requirements that cannot be satisfied + func requirement() -> Any? { return nil } +} + +let unrelatedDiagnostic: Int = nil diff --git a/test/APINotes/versioned.swift b/test/APINotes/versioned.swift index 85dd3e2b4ef70..a3d7353efbef6 100644 --- a/test/APINotes/versioned.swift +++ b/test/APINotes/versioned.swift @@ -18,19 +18,41 @@ import APINotesFrameworkTest func testRenamedTopLevel() { var value = 0.0 - // CHECK-DIAGS-4-NOT: versioned.swift:[[@LINE+1]] + // CHECK-DIAGS-4-NOT: versioned.swift:[[@LINE+1]]: accept(&value) // CHECK-DIAGS-3: versioned.swift:[[@LINE-1]]:3: error: 'accept' has been renamed to 'acceptPointer(_:)' // CHECK-DIAGS-3: note: 'accept' was introduced in Swift 4 - // CHECK-DIAGS-4-NOT: versioned.swift:[[@LINE+1]] + // CHECK-DIAGS-3-NOT: versioned.swift:[[@LINE+1]]: acceptPointer(&value) // CHECK-DIAGS-4: versioned.swift:[[@LINE-1]]:3: error: 'acceptPointer' has been renamed to 'accept(_:)' // CHECK-DIAGS-4: note: 'acceptPointer' was obsoleted in Swift 4 acceptDoublePointer(&value) // CHECK-DIAGS: versioned.swift:[[@LINE-1]]:3: error: 'acceptDoublePointer' has been renamed to - // CHECK-DIAGS-4: 'accept(_:)' - // CHECK-DIAGS-3: 'acceptPointer(_:)' + // CHECK-DIAGS-4-SAME: 'accept(_:)' + // CHECK-DIAGS-3-SAME: 'acceptPointer(_:)' // CHECK-DIAGS: note: 'acceptDoublePointer' was obsoleted in Swift 3 + + oldAcceptDoublePointer(&value) + // CHECK-DIAGS: versioned.swift:[[@LINE-1]]:3: error: 'oldAcceptDoublePointer' has been renamed to + // CHECK-DIAGS-4-SAME: 'accept(_:)' + // CHECK-DIAGS-3-SAME: 'acceptPointer(_:)' + // CHECK-DIAGS: note: 'oldAcceptDoublePointer' has been explicitly marked unavailable here + + _ = SomeCStruct() + // CHECK-DIAGS: versioned.swift:[[@LINE-1]]:7: error: 'SomeCStruct' has been renamed to + // CHECK-DIAGS-4-SAME: 'VeryImportantCStruct' + // CHECK-DIAGS-3-SAME: 'ImportantCStruct' + // CHECK-DIAGS: note: 'SomeCStruct' was obsoleted in Swift 3 + + // CHECK-DIAGS-3-NOT: versioned.swift:[[@LINE+1]]: + _ = ImportantCStruct() + // CHECK-DIAGS-4: versioned.swift:[[@LINE-1]]:7: error: 'ImportantCStruct' has been renamed to 'VeryImportantCStruct' + // CHECK-DIAGS-4: note: 'ImportantCStruct' was obsoleted in Swift 4 + + // CHECK-DIAGS-4-NOT: versioned.swift:[[@LINE+1]]: + _ = VeryImportantCStruct() + // CHECK-DIAGS-3: versioned.swift:[[@LINE-1]]:7: error: 'VeryImportantCStruct' has been renamed to 'ImportantCStruct' + // CHECK-DIAGS-3: note: 'VeryImportantCStruct' was introduced in Swift 4 }