From 7c3cf1d17bdd4211d0108586a24ddb1f3d55edbe Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 7 Feb 2020 20:31:44 -0500 Subject: [PATCH] ClangImporter: Fix mirroring of instance properties as static methods on NSObject Because all metaclasses ultimately inherit from NSObject, instance members of NSObject are also visible as static members of NSObject. If the instance member is a property, we import the getter as an ordinary static method, and not a static property. The lazy loading path normally checks for the presence of alternate decls with the same name, but it was failing to do this check if the imported decl was a property and the alternate decl was attached to the accessor and not the property itself. This wasn't a problem until recently, because we weren't lazy loading members of NSObject itself, since it had protocol conformances; now that we are, this problem was exposed. Fixes . --- lib/ClangImporter/ClangImporter.cpp | 11 +++++++++++ .../mirror_instance_property_static_method.swift | 9 +++++++++ .../clang-importer-sdk/usr/include/objc/NSObject.h | 4 ++++ 3 files changed, 24 insertions(+) create mode 100644 test/ClangImporter/mirror_instance_property_static_method.swift diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 09575f46b201e..6cc87200364bd 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -3787,6 +3787,17 @@ ClangImporter::Implementation::loadNamedMembers( Members.push_back(V); } } + + // If the property's accessors have alternate decls, we might have + // to import those too. + if (auto *ASD = dyn_cast(TD)) { + for (auto *AD : ASD->getAllAccessors()) { + for (auto *D : getAlternateDecls(AD)) { + if (D->getBaseName() == N) + Members.push_back(D); + } + } + } } } diff --git a/test/ClangImporter/mirror_instance_property_static_method.swift b/test/ClangImporter/mirror_instance_property_static_method.swift new file mode 100644 index 0000000000000..7a73bcb7065f3 --- /dev/null +++ b/test/ClangImporter/mirror_instance_property_static_method.swift @@ -0,0 +1,9 @@ +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil %s -verify +// REQUIRES: objc_interop + +import Foundation + +func mirrorInstancePropertyAsStaticMethod() { + // Instance properties are mirrored as static _methods_. Make sure this works. + let _: AnyClass = NSObject.classForCoder() +} diff --git a/test/Inputs/clang-importer-sdk/usr/include/objc/NSObject.h b/test/Inputs/clang-importer-sdk/usr/include/objc/NSObject.h index a403cccf01ea5..a86f7b8851669 100644 --- a/test/Inputs/clang-importer-sdk/usr/include/objc/NSObject.h +++ b/test/Inputs/clang-importer-sdk/usr/include/objc/NSObject.h @@ -27,6 +27,10 @@ @property (readonly) NSInteger hash; @end +@interface NSObject (Coding) +- (Class)classForCoder; +@end + @interface A : NSObject - (int)method:(int)arg withDouble:(double)d; + (int)classMethod;