summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp42
-rw-r--r--clang/test/SemaObjC/kindof.m13
-rw-r--r--clang/test/SemaObjC/multiple-method-names.m4
3 files changed, 45 insertions, 14 deletions
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 58ee123688d..8090bec4fab 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -3213,22 +3213,43 @@ void Sema::addMethodToGlobalList(ObjCMethodList *List,
// We've seen a method with this name, see if we have already seen this type
// signature.
- ObjCMethodList *Head = List;
ObjCMethodList *Previous = List;
+ ObjCMethodList *ListWithSameDeclaration = nullptr;
for (; List; Previous = List, List = List->getNext()) {
// If we are building a module, keep all of the methods.
if (getLangOpts().CompilingModule)
continue;
+ bool SameDeclaration = MatchTwoMethodDeclarations(Method,
+ List->getMethod());
// Looking for method with a type bound requires the correct context exists.
- // We need to insert this method into the list if the context is different.
- if (!MatchTwoMethodDeclarations(Method, List->getMethod()) ||
+ // We need to insert a method into the list if the context is different.
+ // If the method's declaration matches the list
+ // a> the method belongs to a different context: we need to insert it, in
+ // order to emit the availability message, we need to prioritize over
+ // availability among the methods with the same declaration.
+ // b> the method belongs to the same context: there is no need to insert a
+ // new entry.
+ // If the method's declaration does not match the list, we insert it to the
+ // end.
+ if (!SameDeclaration ||
!isMethodContextSameForKindofLookup(Method, List->getMethod())) {
// Even if two method types do not match, we would like to say
// there is more than one declaration so unavailability/deprecated
// warning is not too noisy.
if (!Method->isDefined())
List->setHasMoreThanOneDecl(true);
+
+ // For methods with the same declaration, the one that is deprecated
+ // should be put in the front for better diagnostics.
+ if (Method->isDeprecated() && SameDeclaration &&
+ !ListWithSameDeclaration && !List->getMethod()->isDeprecated())
+ ListWithSameDeclaration = List;
+
+ if (Method->isUnavailable() && SameDeclaration &&
+ !ListWithSameDeclaration &&
+ List->getMethod()->getAvailability() < AR_Deprecated)
+ ListWithSameDeclaration = List;
continue;
}
@@ -3265,15 +3286,12 @@ void Sema::addMethodToGlobalList(ObjCMethodList *List,
// This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>();
- // We tried to prioritize the list by putting deprecated and unavailable
- // methods in the front.
- if ((Method->isDeprecated() && !Head->getMethod()->isDeprecated()) ||
- (Method->isUnavailable() &&
- Head->getMethod()->getAvailability() < AR_Deprecated)) {
- auto *List = new (Mem) ObjCMethodList(*Head);
- // FIXME: should we clear the other bits in Head?
- Head->setMethod(Method);
- Head->setNext(List);
+ // We insert it right before ListWithSameDeclaration.
+ if (ListWithSameDeclaration) {
+ auto *List = new (Mem) ObjCMethodList(*ListWithSameDeclaration);
+ // FIXME: should we clear the other bits in ListWithSameDeclaration?
+ ListWithSameDeclaration->setMethod(Method);
+ ListWithSameDeclaration->setNext(List);
return;
}
diff --git a/clang/test/SemaObjC/kindof.m b/clang/test/SemaObjC/kindof.m
index 95c7f993d17..919ca960a9d 100644
--- a/clang/test/SemaObjC/kindof.m
+++ b/clang/test/SemaObjC/kindof.m
@@ -25,6 +25,7 @@ __attribute__((objc_root_class))
@end
@interface NSString : NSObject <NSCopying> // expected-note{{receiver is instance of class declared here}}
+- (void)compare:(NSString *)string;
- (NSString *)stringByAppendingString:(NSString *)string;
+ (instancetype)string;
@end
@@ -289,6 +290,18 @@ void foo() {
}
}
+typedef const struct CGPath *CGPathRef;
+@interface C : NSObject
+@property (copy) NSString *path;
+@end
+@interface D : NSObject
+@property CGPathRef path __attribute__((availability(macosx,unavailable)));
+@end
+// Make sure we choose "NSString *path" for [s1 path].
+void bar(id s1, id s2) {
+ return [[s1 path] compare:[s2 path]];
+}
+
// ---------------------------------------------------------------------------
// __kindof within specialized types
// ---------------------------------------------------------------------------
diff --git a/clang/test/SemaObjC/multiple-method-names.m b/clang/test/SemaObjC/multiple-method-names.m
index a8707904b56..9fd83b208ab 100644
--- a/clang/test/SemaObjC/multiple-method-names.m
+++ b/clang/test/SemaObjC/multiple-method-names.m
@@ -2,11 +2,11 @@
// PR22047
@interface Face0
-- (void)foo:(float)i; // expected-note {{also found}}
+- (void)foo:(float)i; // expected-note {{using}}
@end
@interface Face1
-- (void)foo:(int)i __attribute__((unavailable)); // expected-note {{using}}
+- (void)foo:(int)i __attribute__((unavailable));
@end
@interface Face2
OpenPOWER on IntegriCloud