Skip to content

Revert "[ClangImporter] Fix edge cases where custom name matches native name" #27914

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

Closed
wants to merge 1 commit into from
Closed
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
14 changes: 3 additions & 11 deletions lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1354,7 +1354,7 @@ bool ClangImporter::importHeader(StringRef header, ModuleDecl *adapter,

// If we've made it to here, this is some header other than the bridging
// header, which means we can no longer rely on one file's modification time
// to invalidate code completion caches. :-(
// to invalid code completion caches. :-(
Impl.setSinglePCHImport(None);

if (!cachedContents.empty() && cachedContents.back() == '\0')
Expand Down Expand Up @@ -3702,16 +3702,8 @@ EffectiveClangContext ClangImporter::Implementation::getEffectiveClangContext(
(nominal->getAttrs().hasAttribute<ObjCAttr>() ||
(!nominal->getParentSourceFile() && nominal->isObjC()))) {
// Map the name. If we can't represent the Swift name in Clang.
Identifier name = nominal->getName();
if (auto objcAttr = nominal->getAttrs().getAttribute<ObjCAttr>()) {
if (auto objcName = objcAttr->getName()) {
if (objcName->getNumArgs() == 0) {
// This is an error if not 0, but it should be caught later.
name = objcName->getSimpleName();
}
}
}
auto clangName = exportName(name);
// FIXME: We should be using the Objective-C name here!
auto clangName = exportName(nominal->getName());
if (!clangName)
return EffectiveClangContext();

Expand Down
72 changes: 13 additions & 59 deletions lib/ClangImporter/ImportDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4532,64 +4532,24 @@ namespace {
}

template <typename T, typename U>
T *resolveSwiftDeclImpl(const U *decl, Identifier name,
bool hasKnownSwiftName, ModuleDecl *overlay) {
T *resolveSwiftDeclImpl(const U *decl, Identifier name, ModuleDecl *overlay) {
const auto &languageVersion =
Impl.SwiftContext.LangOpts.EffectiveLanguageVersion;

auto isMatch = [&](const T *singleResult, bool baseNameMatches) -> bool {
const DeclAttributes &attrs = singleResult->getAttrs();

// Skip versioned variants.
if (attrs.isUnavailableInSwiftVersion(languageVersion))
return false;

// Skip if type not exposed to Objective-C.
// If the base name doesn't match, then a matching
// custom name in an @objc attribute is required.
if (baseNameMatches && !singleResult->isObjC())
return false;

// If Clang decl has a custom Swift name, then we know that
// `name` is the base name we're looking for.
if (hasKnownSwiftName)
return baseNameMatches;

// Skip if a different name is used for Objective-C.
if (auto objcAttr = attrs.getAttribute<ObjCAttr>())
if (auto objcName = objcAttr->getName())
return objcName->getSimpleName() == name;

return baseNameMatches;
};

// First look at Swift types with the same name.
SmallVector<ValueDecl *, 4> results;
overlay->lookupValue(name, NLKind::QualifiedLookup, results);
T *found = nullptr;
for (auto result : results) {
if (auto singleResult = dyn_cast<T>(result)) {
if (isMatch(singleResult, /*baseNameMatches=*/true)) {
if (found)
return nullptr;
found = singleResult;
}
}
}
// Skip versioned variants.
const DeclAttributes &attrs = singleResult->getAttrs();
if (attrs.isUnavailableInSwiftVersion(languageVersion))
continue;

if (!found && !hasKnownSwiftName) {
// Try harder to find a match looking at just custom Objective-C names.
SmallVector<Decl *, 64> results;
overlay->getTopLevelDecls(results);
for (auto result : results) {
if (auto singleResult = dyn_cast<T>(result)) {
// The base name _could_ match but it's irrelevant here.
if (isMatch(singleResult, /*baseNameMatches=*/false)) {
if (found)
return nullptr;
found = singleResult;
}
}
if (found)
return nullptr;

found = singleResult;
}
}

Expand All @@ -4602,16 +4562,15 @@ namespace {

template <typename T, typename U>
T *resolveSwiftDecl(const U *decl, Identifier name,
bool hasKnownSwiftName, ClangModuleUnit *clangModule) {
ClangModuleUnit *clangModule) {
if (auto overlay = clangModule->getOverlayModule())
return resolveSwiftDeclImpl<T>(decl, name, hasKnownSwiftName, overlay);
return resolveSwiftDeclImpl<T>(decl, name, overlay);
if (clangModule == Impl.ImportedHeaderUnit) {
// Use an index-based loop because new owners can come in as we're
// iterating.
for (size_t i = 0; i < Impl.ImportedHeaderOwners.size(); ++i) {
ModuleDecl *owner = Impl.ImportedHeaderOwners[i];
if (T *result = resolveSwiftDeclImpl<T>(decl, name,
hasKnownSwiftName, owner))
if (T *result = resolveSwiftDeclImpl<T>(decl, name, owner))
return result;
}
}
Expand All @@ -4624,8 +4583,7 @@ namespace {
if (!importer::hasNativeSwiftDecl(decl))
return false;
auto wrapperUnit = cast<ClangModuleUnit>(dc->getModuleScopeContext());
swiftDecl = resolveSwiftDecl<T>(decl, name, /*hasCustomSwiftName=*/true,
wrapperUnit);
swiftDecl = resolveSwiftDecl<T>(decl, name, wrapperUnit);
return true;
}

Expand Down Expand Up @@ -4654,15 +4612,13 @@ namespace {
*correctSwiftName);

Identifier name = importedName.getDeclName().getBaseIdentifier();
bool hasKnownSwiftName = importedName.hasCustomName();

// FIXME: Figure out how to deal with incomplete protocols, since that
// notion doesn't exist in Swift.
if (!decl->hasDefinition()) {
// Check if this protocol is implemented in its overlay.
if (auto clangModule = Impl.getClangModuleForDecl(decl, true))
if (auto native = resolveSwiftDecl<ProtocolDecl>(decl, name,
hasKnownSwiftName,
clangModule))
return native;

Expand Down Expand Up @@ -4774,13 +4730,11 @@ namespace {
*correctSwiftName);

auto name = importedName.getDeclName().getBaseIdentifier();
bool hasKnownSwiftName = importedName.hasCustomName();

if (!decl->hasDefinition()) {
// Check if this class is implemented in its overlay.
if (auto clangModule = Impl.getClangModuleForDecl(decl, true)) {
if (auto native = resolveSwiftDecl<ClassDecl>(decl, name,
hasKnownSwiftName,
clangModule)) {
return native;
}
Expand Down
8 changes: 3 additions & 5 deletions lib/ClangImporter/ImportName.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1789,11 +1789,9 @@ ImportedName NameImporter::importName(const clang::NamedDecl *decl,
ImportNameVersion version,
clang::DeclarationName givenName) {
CacheKeyType key(decl, version);
if (!givenName) {
if (auto cachedRes = importNameCache[key]) {
++ImportNameNumCacheHits;
return cachedRes;
}
if (importNameCache.count(key) && !givenName) {
++ImportNameNumCacheHits;
return importNameCache[key];
}
++ImportNameNumCacheMisses;
auto res = importNameImpl(decl, version, givenName);
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/TypeCheckDeclObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1393,7 +1393,7 @@ IsObjCRequest::evaluate(Evaluator &evaluator, ValueDecl *VD) const {
// Classes can be @objc.

// Protocols and enums can also be @objc, but this is covered by the
// isObjC() check at the beginning.
// isObjC() check a the beginning.;
isObjC = shouldMarkAsObjC(VD, /*allowImplicit=*/false);
} else if (auto enumDecl = dyn_cast<EnumDecl>(VD)) {
// Enums can be @objc so long as they have a raw type that is representable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,62 +68,6 @@ SWIFT_PROTOCOL("SwiftProto")
id<SwiftProtoWithCustomName> _Nonnull
convertToProto(SwiftClassWithCustomName *_Nonnull obj);

SWIFT_CLASS("ObjCClass")
__attribute__((objc_root_class))
@interface ObjCClass
@end

SWIFT_CLASS("ImplicitlyObjCClass")
@interface ImplicitlyObjCClass : ObjCClass
@end
void consumeImplicitlyObjCClass(ImplicitlyObjCClass *_Nonnull obj);

SWIFT_CLASS("ExplicitlyObjCClass")
__attribute__((objc_root_class))
@interface ExplicitlyObjCClass
@end
void consumeExplicitlyObjCClass(ExplicitlyObjCClass *_Nonnull obj);

SWIFT_CLASS_NAMED("HasSameCustomNameClass")
__attribute__((objc_root_class))
@interface HasSameCustomNameClass
@end
void consumeHasSameCustomNameClass(HasSameCustomNameClass *_Nonnull obj);

SWIFT_CLASS_NAMED("SwiftNativeTypeHasDifferentCustomNameClass")
__attribute__((objc_root_class))
@interface NativeTypeHasDifferentCustomNameClass
@end
SWIFT_CLASS_NAMED("NativeTypeHasDifferentCustomNameClass")
__attribute__((objc_root_class))
@interface ObjCNativeTypeHasDifferentCustomNameClass
@end
void consumeNativeTypeHasDifferentCustomNameClass(NativeTypeHasDifferentCustomNameClass *_Nonnull obj);
void consumeObjCNativeTypeHasDifferentCustomNameClass(ObjCNativeTypeHasDifferentCustomNameClass *_Nonnull obj);

SWIFT_CLASS_NAMED("SwiftNativeTypeIsNonObjCClass")
__attribute__((objc_root_class))
@interface NativeTypeIsNonObjCClass
@end
void consumeNativeTypeIsNonObjCClass(NativeTypeIsNonObjCClass *_Nonnull obj);

@class ForwardImplicitlyObjCClass;
void consumeForwardImplicitlyObjCClass(ForwardImplicitlyObjCClass *_Nonnull obj);

@class ForwardExplicitlyObjCClass;
void consumeForwardExplicitlyObjCClass(ForwardExplicitlyObjCClass *_Nonnull obj);

@class ForwardHasSameCustomNameClass;
void consumeForwardHasSameCustomNameClass(ForwardHasSameCustomNameClass *_Nonnull obj);

@class ForwardNativeTypeHasDifferentCustomNameClass;
@class ObjCForwardNativeTypeHasDifferentCustomNameClass;
void consumeForwardNativeTypeHasDifferentCustomNameClass(ForwardNativeTypeHasDifferentCustomNameClass *_Nonnull obj);
void consumeObjCForwardNativeTypeHasDifferentCustomNameClass(ObjCForwardNativeTypeHasDifferentCustomNameClass *_Nonnull obj);

@class ForwardNativeTypeIsNonObjCClass;
void consumeForwardNativeTypeIsNonObjCClass(ForwardNativeTypeIsNonObjCClass *_Nonnull obj);

SWIFT_CLASS("BOGUS")
@interface BogusClass
@end
Expand Down
67 changes: 0 additions & 67 deletions test/ClangImporter/MixedSource/Inputs/mixed-framework/Mixed.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,70 +31,3 @@ public class CustomNameClass : CustomName {
@objc func protoMethod()
@objc var protoProperty: Int { get }
}

@objc
public class ObjCClass {
public init() {}
}

public class ImplicitlyObjCClass : ObjCClass {
public override init() { super.init() }
}

@objc
public class ExplicitlyObjCClass {
public init() {}
}

@objc(HasSameCustomNameClass)
public class HasSameCustomNameClass {
public init() {}
}

@objc(ObjCNativeTypeHasDifferentCustomNameClass)
public class NativeTypeHasDifferentCustomNameClass {
public init() {}
}
@objc(NativeTypeHasDifferentCustomNameClass)
public class SwiftNativeTypeHasDifferentCustomNameClass {
public init() {}
}

public class NativeTypeIsNonObjCClass {
public init() {}
}
@objc(NativeTypeIsNonObjCClass)
public class SwiftNativeTypeIsNonObjCClass {
public init() {}
}

public class ForwardImplicitlyObjCClass : ObjCClass {
public override init() { super.init() }
}

@objc
public class ForwardExplicitlyObjCClass {
public init() {}
}

@objc(ForwardHasSameCustomNameClass)
public class ForwardHasSameCustomNameClass {
public init() {}
}

@objc(ObjCForwardNativeTypeHasDifferentCustomNameClass)
public class ForwardNativeTypeHasDifferentCustomNameClass {
public init() {}
}
@objc(ForwardNativeTypeHasDifferentCustomNameClass)
public class SwiftForwardNativeTypeHasDifferentCustomNameClass {
public init() {}
}

public class ForwardNativeTypeIsNonObjCClass {
public init() {}
}
@objc(ForwardNativeTypeIsNonObjCClass)
public class SwiftForwardNativeTypeIsNonObjCClass {
public init() {}
}
28 changes: 0 additions & 28 deletions test/ClangImporter/MixedSource/import-mixed-framework.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,31 +32,3 @@ func testAnyObject(_ obj: AnyObject) {
obj.protoMethod()
_ = obj.protoProperty
}

consumeImplicitlyObjCClass(ImplicitlyObjCClass())

consumeExplicitlyObjCClass(ExplicitlyObjCClass())

consumeHasSameCustomNameClass(HasSameCustomNameClass())

consumeNativeTypeHasDifferentCustomNameClass(SwiftNativeTypeHasDifferentCustomNameClass())
consumeObjCNativeTypeHasDifferentCustomNameClass(NativeTypeHasDifferentCustomNameClass())
consumeNativeTypeHasDifferentCustomNameClass(NativeTypeHasDifferentCustomNameClass()) // expected-error {{cannot convert value of type 'NativeTypeHasDifferentCustomNameClass' to expected argument type 'SwiftNativeTypeHasDifferentCustomNameClass'}}
consumeObjCNativeTypeHasDifferentCustomNameClass(SwiftNativeTypeHasDifferentCustomNameClass()) // expected-error {{cannot convert value of type 'SwiftNativeTypeHasDifferentCustomNameClass' to expected argument type 'NativeTypeHasDifferentCustomNameClass'}}

consumeNativeTypeIsNonObjCClass(SwiftNativeTypeIsNonObjCClass())
consumeNativeTypeIsNonObjCClass(NativeTypeIsNonObjCClass()) // expected-error {{cannot convert value of type 'NativeTypeIsNonObjCClass' to expected argument type 'SwiftNativeTypeIsNonObjCClass'}}

consumeForwardImplicitlyObjCClass(ForwardImplicitlyObjCClass())

consumeForwardExplicitlyObjCClass(ForwardExplicitlyObjCClass())

consumeForwardHasSameCustomNameClass(ForwardHasSameCustomNameClass())

consumeForwardNativeTypeHasDifferentCustomNameClass(SwiftForwardNativeTypeHasDifferentCustomNameClass())
consumeObjCForwardNativeTypeHasDifferentCustomNameClass(ForwardNativeTypeHasDifferentCustomNameClass())
consumeForwardNativeTypeHasDifferentCustomNameClass(ForwardNativeTypeHasDifferentCustomNameClass()) // expected-error {{cannot convert value of type 'ForwardNativeTypeHasDifferentCustomNameClass' to expected argument type 'SwiftForwardNativeTypeHasDifferentCustomNameClass'}}
consumeObjCForwardNativeTypeHasDifferentCustomNameClass(SwiftForwardNativeTypeHasDifferentCustomNameClass()) // expected-error {{cannot convert value of type 'SwiftForwardNativeTypeHasDifferentCustomNameClass' to expected argument type 'ForwardNativeTypeHasDifferentCustomNameClass'}}

consumeForwardNativeTypeIsNonObjCClass(SwiftForwardNativeTypeIsNonObjCClass())
consumeForwardNativeTypeIsNonObjCClass(ForwardNativeTypeIsNonObjCClass()) // expected-error {{cannot convert value of type 'ForwardNativeTypeIsNonObjCClass' to expected argument type 'SwiftForwardNativeTypeIsNonObjCClass'}}