Skip to content

Several small fixes for importing alternate names #7756

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions include/swift/ClangImporter/ClangImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
52 changes: 27 additions & 25 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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()) {
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -4665,19 +4672,14 @@ Decl *SwiftDeclConverter::importSwift2TypeAlias(const clang::NamedDecl *decl,

// Create the type alias.
auto alias = Impl.createDeclWithClangNode<TypeAliasDecl>(
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;
}
Expand Down Expand Up @@ -6516,7 +6518,7 @@ getSwiftNameFromClangName(StringRef replacement) {
if (!clangDecl)
return "";

auto importedName = importFullName(clangDecl, ImportNameVersion::Swift3);
auto importedName = importFullName(clangDecl, CurrentVersion);
if (!importedName)
return "";

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
Expand Down
6 changes: 3 additions & 3 deletions lib/ClangImporter/ImportType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -13,5 +15,8 @@ __attribute__((objc_root_class))
-(nonnull id)methodWithA:(nonnull id)a;
@end

#endif // __OBJC__

#import <APINotesFrameworkTest/Properties.h>
#endif
#import <APINotesFrameworkTest/Protocols.h>
#import <APINotesFrameworkTest/Types.h>
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#ifdef __OBJC__
#pragma clang assume_nonnull begin

__attribute__((objc_root_class))
Expand Down Expand Up @@ -33,3 +34,4 @@ __attribute__((objc_root_class))
@end

#pragma clang assume_nonnull end
#endif // __OBJC__
Original file line number Diff line number Diff line change
@@ -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__
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma clang assume_nonnull begin

struct __attribute__((swift_name("VeryImportantCStruct"))) SomeCStruct {
int field;
};

#pragma clang assume_nonnull end
16 changes: 16 additions & 0 deletions test/APINotes/versioned-objc.swift
Original file line number Diff line number Diff line change
@@ -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
30 changes: 26 additions & 4 deletions test/APINotes/versioned.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
}