mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[ClangImporter] Don't put method redeclarations in a member list.
Previously we'd try to put the same method into the list of members multiple times--once for each redeclaration in the @interface. This led to an assertion failure. Checking the canonical decl isn't super cheap, but the ObjCMethodDecl redeclaration infrastructure seems to be fairly broken. We can revisit this later. There's also a test for what happens when categories get involved. I'm not convinced this is correct behavior, either, and will file an additional bug to look into that at some point. rdar://problem/19039485 Swift SVN r24129
This commit is contained in:
@@ -3848,7 +3848,7 @@ namespace {
|
||||
for (auto m = decl->decls_begin(), mEnd = decl->decls_end();
|
||||
m != mEnd; ++m) {
|
||||
auto nd = dyn_cast<clang::NamedDecl>(*m);
|
||||
if (!nd)
|
||||
if (!nd || nd != nd->getCanonicalDecl())
|
||||
continue;
|
||||
|
||||
auto member = Impl.importDecl(nd);
|
||||
@@ -3865,11 +3865,6 @@ namespace {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this member is a method that is a getter or setter for a property
|
||||
// that was imported, don't add it to the list of members so it won't
|
||||
// be found by name lookup. This eliminates the ambiguity between
|
||||
// property names and getter names (by choosing to only have a
|
||||
// variable).
|
||||
if (auto objcMethod = dyn_cast<clang::ObjCMethodDecl>(nd)) {
|
||||
// If there is a special declaration associated with this member,
|
||||
// add it now.
|
||||
@@ -3906,6 +3901,11 @@ namespace {
|
||||
// Import explicit properties as instance properties, not as separate
|
||||
// getter and setter methods.
|
||||
if (!Impl.isAccessibilityDecl(objcMethod)) {
|
||||
// If this member is a method that is a getter or setter for a
|
||||
// propertythat was imported, don't add it to the list of members
|
||||
// so it won't be found by name lookup. This eliminates the
|
||||
// ambiguity between property names and getter names (by choosing
|
||||
// to only have a variable).
|
||||
if (objcMethod->isPropertyAccessor()) {
|
||||
auto prop = objcMethod->findPropertyDecl(/*checkOverrides=*/false);
|
||||
assert(prop);
|
||||
|
||||
@@ -92,3 +92,10 @@ __weak id globalWeakVar;
|
||||
@interface DeprecatedFactoryMethod
|
||||
+ (instancetype)deprecatedFactoryMethod __attribute__((deprecated("use something newer")));
|
||||
@end
|
||||
|
||||
|
||||
@interface RepeatedMembers : NSObject
|
||||
- (void)repeatedMethod;
|
||||
- (void)anotherMethod;
|
||||
- (void)repeatedMethod __attribute__((deprecated("use something newer")));
|
||||
@end
|
||||
|
||||
@@ -455,3 +455,7 @@ func testFactoryMethodAvailability() {
|
||||
let _ = DeprecatedFactoryMethod() // expected-error{{'init()' is unavailable: use something newer}}
|
||||
}
|
||||
|
||||
func testRepeatedMembers(obj: RepeatedMembers) {
|
||||
obj.repeatedMethod()
|
||||
}
|
||||
|
||||
|
||||
@@ -254,3 +254,17 @@ class <loc>FooClassDerived</loc> : <ref:Class>FooClassBase</ref>, <ref:Protocol>
|
||||
<decl:TypeAlias>typealias <loc>FooCFTypeRef</loc> = <ref:Class>FooCFType</ref></decl>
|
||||
<decl:Func>@availability(*, unavailable, message="Core Foundation objects are automatically memory managed")
|
||||
func <loc>FooCFTypeRelease(_: <ref:Class>FooCFType</ref>!)</loc></decl>
|
||||
<decl:Class>class <loc>FooRepeatedMembers</loc> : <ref:Class>FooClassBase</ref> {
|
||||
<decl:Func>func <loc>repeatedMethod()</loc></decl>
|
||||
<decl:Func>func <loc>anotherMethod()</loc></decl>
|
||||
<decl:Constructor><loc>init!()</loc></decl>
|
||||
<decl:Constructor>convenience <loc>init!(float f: <ref:Struct>Float</ref>)</loc></decl>
|
||||
}</decl>
|
||||
<decl:Extension>extension <ref:Class><loc>FooRepeatedMembers</ref></loc> {
|
||||
<decl:Var>var <loc>repeatedPropertyInCategory</loc>: <ref:Struct>Int32</ref></decl>
|
||||
<decl:Func>func <loc>repeatedMethodInCategory()</loc></decl>
|
||||
<decl:Var>var <loc>repeatedPropertyFromCategory</loc>: <ref:Struct>Int32</ref></decl>
|
||||
<decl:Func>func <loc>repeatedMethodFromCategory()</loc></decl>
|
||||
}</decl>
|
||||
<decl:Extension>extension <ref:Class><loc>FooRepeatedMembers</ref></loc> {
|
||||
}</decl>
|
||||
|
||||
@@ -260,4 +260,27 @@ struct _InternalStruct {
|
||||
typedef struct __FooCFType *FooCFTypeRef;
|
||||
void FooCFTypeRelease(FooCFTypeRef);
|
||||
|
||||
|
||||
@interface FooRepeatedMembers : FooClassBase
|
||||
- (void)repeatedMethod;
|
||||
- (void)anotherMethod;
|
||||
- (void)repeatedMethod;
|
||||
|
||||
@property int repeatedPropertyInCategory;
|
||||
- (void)repeatedMethodInCategory;
|
||||
@end
|
||||
|
||||
@interface FooRepeatedMembers (Category)
|
||||
@property int repeatedPropertyInCategory;
|
||||
- (void)repeatedMethodInCategory;
|
||||
|
||||
@property int repeatedPropertyFromCategory;
|
||||
- (void)repeatedMethodFromCategory;
|
||||
@end
|
||||
|
||||
@interface FooRepeatedMembers (AnotherCategory)
|
||||
@property int repeatedPropertyFromCategory;
|
||||
- (void)repeatedMethodFromCategory;
|
||||
@end
|
||||
|
||||
#endif /* ! __FOO_H__ */
|
||||
|
||||
@@ -254,6 +254,20 @@ class FooUnavailableMembers : FooClassBase {
|
||||
typealias FooCFTypeRef = FooCFType
|
||||
@availability(*, unavailable, message="Core Foundation objects are automatically memory managed")
|
||||
func FooCFTypeRelease(_: FooCFType!)
|
||||
class FooRepeatedMembers : FooClassBase {
|
||||
func repeatedMethod()
|
||||
func anotherMethod()
|
||||
init!()
|
||||
convenience init!(float f: Float)
|
||||
}
|
||||
extension FooRepeatedMembers {
|
||||
var repeatedPropertyInCategory: Int32
|
||||
func repeatedMethodInCategory()
|
||||
var repeatedPropertyFromCategory: Int32
|
||||
func repeatedMethodFromCategory()
|
||||
}
|
||||
extension FooRepeatedMembers {
|
||||
}
|
||||
func fooSubFunc1(a: Int32) -> Int32
|
||||
struct FooSubEnum1 {
|
||||
init(_ value: UInt32)
|
||||
|
||||
@@ -308,3 +308,21 @@ class FooUnavailableMembers : FooClassBase {
|
||||
typealias FooCFTypeRef = FooCFType
|
||||
@availability(*, unavailable, message="Core Foundation objects are automatically memory managed")
|
||||
func FooCFTypeRelease(_: FooCFType!)
|
||||
|
||||
class FooRepeatedMembers : FooClassBase {
|
||||
func repeatedMethod()
|
||||
func anotherMethod()
|
||||
init!()
|
||||
convenience init!(float f: Float)
|
||||
}
|
||||
|
||||
extension FooRepeatedMembers {
|
||||
var repeatedPropertyInCategory: Int32
|
||||
func repeatedMethodInCategory()
|
||||
|
||||
var repeatedPropertyFromCategory: Int32
|
||||
func repeatedMethodFromCategory()
|
||||
}
|
||||
|
||||
extension FooRepeatedMembers {
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ func testCompleteModuleQualifiedFoo2() {
|
||||
Foo#^CLANG_QUAL_FOO_2^#
|
||||
// If the number of results below changes, then you need to add a result to the
|
||||
// list below.
|
||||
// CLANG_QUAL_FOO_2: Begin completions, 61 items
|
||||
// CLANG_QUAL_FOO_2: Begin completions, 62 items
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule: .FooClassBase[#FooClassBase#]{{$}}
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule: .FooClassDerived[#FooClassDerived#]{{$}}
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule: .ClassWithInternalProt[#ClassWithInternalProt#]{{$}}
|
||||
@@ -206,6 +206,7 @@ func testCompleteModuleQualifiedFoo2() {
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule: .FooUnavailableMembers[#FooUnavailableMembers#]
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[TypeAlias]/OtherModule: .FooTypedef1[#Int32#]{{$}}
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[TypeAlias]/OtherModule: .FooCFTypeRef[#FooCFType#]{{$}}
|
||||
// CLANG_QUAL_FOO_2-DAG: Decl[Class]/OtherModule: .FooRepeatedMembers[#FooRepeatedMembers#]{{$}}
|
||||
// CLANG_QUAL_FOO_2: End completions
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user