Rework how ObjC method inherit deprecated/availability.

New rule:
- Method decls in @implementation are considered "redeclarations"
  and inherit deprecated/availability from the @interface.
- All other cases are consider overrides, which do not inherit
  deprecated/availability.  For example:

  (a) @interface redeclares a method in an adopted protocol.
  (b) A subclass redeclares a method in a superclass.
  (c) A protocol redeclares a method from another protocol it adopts.

The idea is that API authors should have the ability to easily
move availability/deprecated up and down a class/protocol hierarchy.
A redeclaration means that the availability/deprecation is a blank
slate.

Fixes <rdar://problem/13574571>

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178937 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index e9116bc..84d992c 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2769,7 +2769,10 @@
                                 ObjCMethodDecl *oldMethod) {
 
   // Merge the attributes, including deprecated/unavailable
-  mergeDeclAttributes(newMethod, oldMethod, AMK_Override);
+  AvailabilityMergeKind MergeKind =
+    isa<ObjCImplDecl>(newMethod->getDeclContext()) ? AMK_Redeclaration
+                                                   : AMK_Override;
+  mergeDeclAttributes(newMethod, oldMethod, MergeKind);
 
   // Merge attributes from the parameters.
   ObjCMethodDecl::param_const_iterator oi = oldMethod->param_begin(),
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 982e7a5..f832809 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -2246,8 +2246,11 @@
       MergedObsoleted == Obsoleted)
     return NULL;
 
+  // Only create a new attribute if !Override, but we want to do
+  // the checking.
   if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced,
-                             MergedDeprecated, MergedObsoleted)) {
+                             MergedDeprecated, MergedObsoleted) &&
+      !Override) {
     return ::new (Context) AvailabilityAttr(Range, Context, Platform,
                                             Introduced, Deprecated,
                                             Obsoleted, IsUnavailable, Message,