<div dir="auto">We currently rely on this for chromium; that's how the warning used to work when I added it. What's the transition plan? Can we have a flag to incrementally transition to whatever the new way is? (Is it documented anywhere?)<div dir="auto"><br></div><div dir="auto">Also, I think the replacement somehow needs the new runtime stuff from libbuiltin -- does the driver know when to add that to the link line? If so, where's the logic for that? If not, what library is supposed to provide the runtime check function?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Jul 5, 2017 7:09 PM, "Erik Pilkington via cfe-commits" <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: epilk<br>
Date: Wed Jul  5 10:08:56 2017<br>
New Revision: 307175<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=307175&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=307175&view=rev</a><br>
Log:<br>
[Sema] Don't allow -Wunguarded-availability to be silenced with redecls<br>
<br>
Differential revision: <a href="https://reviews.llvm.org/D33816" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D33816</a><br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
    cfe/trunk/include/clang/Sema/<wbr>DelayedDiagnostic.h<br>
    cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
    cfe/trunk/lib/Sema/<wbr>DelayedDiagnostic.cpp<br>
    cfe/trunk/lib/Sema/<wbr>SemaDeclAttr.cpp<br>
    cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp<br>
    cfe/trunk/test/Sema/attr-<wbr>availability.c<br>
    cfe/trunk/test/Sema/attr-<wbr>deprecated.c<br>
    cfe/trunk/test/Sema/attr-<wbr>unavailable-message.c<br>
    cfe/trunk/test/SemaCXX/attr-<wbr>deprecated.cpp<br>
    cfe/trunk/test/SemaObjC/attr-<wbr>availability.m<br>
    cfe/trunk/test/SemaObjC/<wbr>unguarded-availability-new.m<br>
    cfe/trunk/test/SemaObjC/<wbr>unguarded-availability.m<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=307175&r1=307174&r2=307175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Basic/<wbr>DiagnosticSemaKinds.td?rev=<wbr>307175&r1=307174&r2=307175&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td Wed Jul  5 10:08:56 2017<br>
@@ -2880,7 +2880,7 @@ def warn_partial_availability : Warning<<br>
 def warn_partial_availability_new : Warning<warn_partial_<wbr>availability.Text>,<br>
   InGroup<<wbr>UnguardedAvailabilityNew>;<br>
 def note_partial_availability_<wbr>silence : Note<<br>
-  "explicitly redeclare %0 to silence this warning">;<br>
+  "annotate %select{%1|anonymous %1}0 with an availability attribute to silence">;<br>
 def note_unguarded_available_<wbr>silence : Note<<br>
   "enclose %0 in %select{an @available|a __builtin_available}1 check to silence"<br>
   " this warning">;<br>
<br>
Modified: cfe/trunk/include/clang/Sema/<wbr>DelayedDiagnostic.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DelayedDiagnostic.h?rev=307175&r1=307174&r2=307175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Sema/DelayedDiagnostic.<wbr>h?rev=307175&r1=307174&r2=<wbr>307175&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Sema/<wbr>DelayedDiagnostic.h (original)<br>
+++ cfe/trunk/include/clang/Sema/<wbr>DelayedDiagnostic.h Wed Jul  5 10:08:56 2017<br>
@@ -124,7 +124,8 @@ public:<br>
<br>
   static DelayedDiagnostic makeAvailability(<wbr>AvailabilityResult AR,<br>
                                             SourceLocation Loc,<br>
-                                            const NamedDecl *D,<br>
+                                            const NamedDecl *ReferringDecl,<br>
+                                            const NamedDecl *OffendingDecl,<br>
                                             const ObjCInterfaceDecl *UnknownObjCClass,<br>
                                             const ObjCPropertyDecl  *ObjCProperty,<br>
                                             StringRef Msg,<br>
@@ -164,9 +165,13 @@ public:<br>
     return *reinterpret_cast<const AccessedEntity*>(AccessData);<br>
   }<br>
<br>
-  const NamedDecl *getAvailabilityDecl() const {<br>
+  const NamedDecl *getAvailabilityReferringDecl(<wbr>) const {<br>
     assert(Kind == Availability && "Not an availability diagnostic.");<br>
-    return AvailabilityData.Decl;<br>
+    return AvailabilityData.<wbr>ReferringDecl;<br>
+  }<br>
+<br>
+  const NamedDecl *getAvailabilityOffendingDecl(<wbr>) const {<br>
+    return AvailabilityData.<wbr>OffendingDecl;<br>
   }<br>
<br>
   StringRef getAvailabilityMessage() const {<br>
@@ -213,7 +218,8 @@ public:<br>
 private:<br>
<br>
   struct AD {<br>
-    const NamedDecl *Decl;<br>
+    const NamedDecl *ReferringDecl;<br>
+    const NamedDecl *OffendingDecl;<br>
     const ObjCInterfaceDecl *UnknownObjCClass;<br>
     const ObjCPropertyDecl  *ObjCProperty;<br>
     const char *Message;<br>
<br>
Modified: cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=307175&r1=307174&r2=307175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Sema/Sema.h?rev=307175&<wbr>r1=307174&r2=307175&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Sema/<wbr>Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/<wbr>Sema.h Wed Jul  5 10:08:56 2017<br>
@@ -3881,7 +3881,9 @@ public:<br>
<br>
   void redelayDiagnostics(sema::<wbr>DelayedDiagnosticPool &pool);<br>
<br>
-  void EmitAvailabilityWarning(<wbr>AvailabilityResult AR, NamedDecl *D,<br>
+  void EmitAvailabilityWarning(<wbr>AvailabilityResult AR,<br>
+                               const NamedDecl *ReferringDecl,<br>
+                               const NamedDecl *OffendingDecl,<br>
                                StringRef Message, SourceLocation Loc,<br>
                                const ObjCInterfaceDecl *UnknownObjCClass,<br>
                                const ObjCPropertyDecl *ObjCProperty,<br>
@@ -10413,16 +10415,14 @@ public:<br>
     return OriginalLexicalContext ? OriginalLexicalContext : CurContext;<br>
   }<br>
<br>
-  /// \brief The diagnostic we should emit for \c D, or \c AR_Available.<br>
-  ///<br>
-  /// \param D The declaration to check. Note that this may be altered to point<br>
-  /// to another declaration that \c D gets it's availability from. i.e., we<br>
-  /// walk the list of typedefs to find an availability attribute.<br>
+  /// The diagnostic we should emit for \c D, and the declaration that<br>
+  /// originated it, or \c AR_Available.<br>
   ///<br>
+  /// \param D The declaration to check.<br>
   /// \param Message If non-null, this will be populated with the message from<br>
   /// the availability attribute that is selected.<br>
-  AvailabilityResult ShouldDiagnoseAvailabilityOfDe<wbr>cl(NamedDecl *&D,<br>
-                                                      std::string *Message);<br>
+  std::pair<AvailabilityResult, const NamedDecl *><br>
+  ShouldDiagnoseAvailabilityOfDe<wbr>cl(const NamedDecl *D, std::string *Message);<br>
<br>
   const DeclContext *getCurObjCLexicalContext() const {<br>
     const DeclContext *DC = getCurLexicalContext();<br>
<br>
Modified: cfe/trunk/lib/Sema/<wbr>DelayedDiagnostic.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DelayedDiagnostic.cpp?rev=307175&r1=307174&r2=307175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>DelayedDiagnostic.cpp?rev=<wbr>307175&r1=307174&r2=307175&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/<wbr>DelayedDiagnostic.cpp (original)<br>
+++ cfe/trunk/lib/Sema/<wbr>DelayedDiagnostic.cpp Wed Jul  5 10:08:56 2017<br>
@@ -22,7 +22,8 @@ using namespace sema;<br>
 DelayedDiagnostic<br>
 DelayedDiagnostic::<wbr>makeAvailability(<wbr>AvailabilityResult AR,<br>
                                     SourceLocation Loc,<br>
-                                    const NamedDecl *D,<br>
+                                    const NamedDecl *ReferringDecl,<br>
+                                    const NamedDecl *OffendingDecl,<br>
                                     const ObjCInterfaceDecl *UnknownObjCClass,<br>
                                     const ObjCPropertyDecl  *ObjCProperty,<br>
                                     StringRef Msg,<br>
@@ -31,7 +32,8 @@ DelayedDiagnostic::<wbr>makeAvailability(Avai<br>
   DD.Kind = Availability;<br>
   DD.Triggered = false;<br>
   DD.Loc = Loc;<br>
-  DD.AvailabilityData.Decl = D;<br>
+  DD.AvailabilityData.<wbr>ReferringDecl = ReferringDecl;<br>
+  DD.AvailabilityData.<wbr>OffendingDecl = OffendingDecl;<br>
   DD.AvailabilityData.<wbr>UnknownObjCClass = UnknownObjCClass;<br>
   DD.AvailabilityData.<wbr>ObjCProperty = ObjCProperty;<br>
   char *MessageData = nullptr;<br>
<br>
Modified: cfe/trunk/lib/Sema/<wbr>SemaDeclAttr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=307175&r1=307174&r2=307175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaDeclAttr.cpp?rev=307175&<wbr>r1=307174&r2=307175&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/<wbr>SemaDeclAttr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/<wbr>SemaDeclAttr.cpp Wed Jul  5 10:08:56 2017<br>
@@ -6929,8 +6929,34 @@ shouldDiagnoseAvailabilityByDe<wbr>fault(cons<br>
          DeclVersion >= ForceAvailabilityFromVersion;<br>
 }<br>
<br>
+static NamedDecl *findEnclosingDeclToAnnotate(<wbr>Decl *OrigCtx) {<br>
+  for (Decl *Ctx = OrigCtx; Ctx;<br>
+       Ctx = cast_or_null<Decl>(Ctx-><wbr>getDeclContext())) {<br>
+    if (isa<TagDecl>(Ctx) || isa<FunctionDecl>(Ctx) || isa<ObjCMethodDecl>(Ctx))<br>
+      return cast<NamedDecl>(Ctx);<br>
+    if (auto *CD = dyn_cast<ObjCContainerDecl>(<wbr>Ctx)) {<br>
+      if (auto *Imp = dyn_cast<ObjCImplDecl>(Ctx))<br>
+        return Imp->getClassInterface();<br>
+      return CD;<br>
+    }<br>
+  }<br>
+<br>
+  return dyn_cast<NamedDecl>(OrigCtx);<br>
+}<br>
+<br>
+/// Actually emit an availability diagnostic for a reference to an unavailable<br>
+/// decl.<br>
+///<br>
+/// \param Ctx The context that the reference occurred in<br>
+/// \param ReferringDecl The exact declaration that was referenced.<br>
+/// \param OffendingDecl A related decl to \c ReferringDecl that has an<br>
+/// availability attribute corrisponding to \c K attached to it. Note that this<br>
+/// may not be the same as ReferringDecl, i.e. if an EnumDecl is annotated and<br>
+/// we refer to a member EnumConstantDecl, ReferringDecl is the EnumConstantDecl<br>
+/// and OffendingDecl is the EnumDecl.<br>
 static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,<br>
-                                      Decl *Ctx, const NamedDecl *D,<br>
+                                      Decl *Ctx, const NamedDecl *ReferringDecl,<br>
+                                      const NamedDecl *OffendingDecl,<br>
                                       StringRef Message, SourceLocation Loc,<br>
                                       const ObjCInterfaceDecl *UnknownObjCClass,<br>
                                       const ObjCPropertyDecl *ObjCProperty,<br>
@@ -6938,7 +6964,7 @@ static void DoEmitAvailabilityWarning(Se<br>
   // Diagnostics for deprecated or unavailable.<br>
   unsigned diag, diag_message, diag_fwdclass_message;<br>
   unsigned diag_available_here = diag::note_availability_<wbr>specified_here;<br>
-  SourceLocation NoteLocation = D->getLocation();<br>
+  SourceLocation NoteLocation = OffendingDecl->getLocation();<br>
<br>
   // Matches 'diag::note_property_<wbr>attribute' options.<br>
   unsigned property_note_select;<br>
@@ -6947,7 +6973,7 @@ static void DoEmitAvailabilityWarning(Se<br>
   unsigned available_here_select_kind;<br>
<br>
   VersionTuple DeclVersion;<br>
-  if (const AvailabilityAttr *AA = getAttrForPlatform(S.Context, D))<br>
+  if (const AvailabilityAttr *AA = getAttrForPlatform(S.Context, OffendingDecl))<br>
     DeclVersion = AA->getIntroduced();<br>
<br>
   if (!<wbr>ShouldDiagnoseAvailabilityInCo<wbr>ntext(S, K, DeclVersion, Ctx))<br>
@@ -6961,7 +6987,7 @@ static void DoEmitAvailabilityWarning(Se<br>
     diag_fwdclass_message = diag::warn_deprecated_<wbr>fwdclass_message;<br>
     property_note_select = /* deprecated */ 0;<br>
     available_here_select_kind = /* deprecated */ 2;<br>
-    if (const auto *attr = D->getAttr<DeprecatedAttr>())<br>
+    if (const auto *attr = OffendingDecl->getAttr<<wbr>DeprecatedAttr>())<br>
       NoteLocation = attr->getLocation();<br>
     break;<br>
<br>
@@ -6973,13 +6999,14 @@ static void DoEmitAvailabilityWarning(Se<br>
     property_note_select = /* unavailable */ 1;<br>
     available_here_select_kind = /* unavailable */ 0;<br>
<br>
-    if (auto attr = D->getAttr<UnavailableAttr>()) {<br>
+    if (auto attr = OffendingDecl->getAttr<<wbr>UnavailableAttr>()) {<br>
       if (attr->isImplicit() && attr->getImplicitReason()) {<br>
         // Most of these failures are due to extra restrictions in ARC;<br>
         // reflect that in the primary diagnostic when applicable.<br>
         auto flagARCError = [&] {<br>
           if (S.getLangOpts().<wbr>ObjCAutoRefCount &&<br>
-              S.getSourceManager().<wbr>isInSystemHeader(D-><wbr>getLocation()))<br>
+              S.getSourceManager().<wbr>isInSystemHeader(<br>
+                  OffendingDecl->getLocation()))<br>
             diag = diag::err_unavailable_in_arc;<br>
         };<br>
<br>
@@ -7022,7 +7049,8 @@ static void DoEmitAvailabilityWarning(Se<br>
     // not specified for deployment targets >= to iOS 11 or equivalent or<br>
     // for declarations that were introduced in iOS 11 (macOS 10.13, ...) or<br>
     // later.<br>
-    const AvailabilityAttr *AA = getAttrForPlatform(S.<wbr>getASTContext(), D);<br>
+    const AvailabilityAttr *AA =<br>
+        getAttrForPlatform(S.<wbr>getASTContext(), OffendingDecl);<br>
     VersionTuple Introduced = AA->getIntroduced();<br>
     bool NewWarning = shouldDiagnoseAvailabilityByDe<wbr>fault(<br>
         S.Context, S.Context.getTargetInfo().<wbr>getPlatformMinVersion(),<br>
@@ -7045,9 +7073,9 @@ static void DoEmitAvailabilityWarning(Se<br>
   CharSourceRange UseRange;<br>
   StringRef Replacement;<br>
   if (K == AR_Deprecated) {<br>
-    if (auto attr = D->getAttr<DeprecatedAttr>())<br>
+    if (auto attr = OffendingDecl->getAttr<<wbr>DeprecatedAttr>())<br>
       Replacement = attr->getReplacement();<br>
-    if (auto attr = getAttrForPlatform(S.Context, D))<br>
+    if (auto attr = getAttrForPlatform(S.Context, OffendingDecl))<br>
       Replacement = attr->getReplacement();<br>
<br>
     if (!Replacement.empty())<br>
@@ -7056,21 +7084,21 @@ static void DoEmitAvailabilityWarning(Se<br>
   }<br>
<br>
   if (!Message.empty()) {<br>
-    S.Diag(Loc, diag_message) << D << Message<br>
+    S.Diag(Loc, diag_message) << ReferringDecl << Message<br>
       << (UseRange.isValid() ?<br>
           FixItHint::CreateReplacement(<wbr>UseRange, Replacement) : FixItHint());<br>
     if (ObjCProperty)<br>
       S.Diag(ObjCProperty-><wbr>getLocation(), diag::note_property_attribute)<br>
           << ObjCProperty->getDeclName() << property_note_select;<br>
   } else if (!UnknownObjCClass) {<br>
-    S.Diag(Loc, diag) << D<br>
+    S.Diag(Loc, diag) << ReferringDecl<br>
       << (UseRange.isValid() ?<br>
           FixItHint::CreateReplacement(<wbr>UseRange, Replacement) : FixItHint());<br>
     if (ObjCProperty)<br>
       S.Diag(ObjCProperty-><wbr>getLocation(), diag::note_property_attribute)<br>
           << ObjCProperty->getDeclName() << property_note_select;<br>
   } else {<br>
-    S.Diag(Loc, diag_fwdclass_message) << D<br>
+    S.Diag(Loc, diag_fwdclass_message) << ReferringDecl<br>
       << (UseRange.isValid() ?<br>
           FixItHint::CreateReplacement(<wbr>UseRange, Replacement) : FixItHint());<br>
     S.Diag(UnknownObjCClass-><wbr>getLocation(), diag::note_forward_class);<br>
@@ -7078,16 +7106,16 @@ static void DoEmitAvailabilityWarning(Se<br>
<br>
   // The declaration can have multiple availability attributes, we are looking<br>
   // at one of them.<br>
-  const AvailabilityAttr *A = getAttrForPlatform(S.Context, D);<br>
+  const AvailabilityAttr *A = getAttrForPlatform(S.Context, OffendingDecl);<br>
   if (A && A->isInherited()) {<br>
-    for (const Decl *Redecl = D->getMostRecentDecl(); Redecl;<br>
+    for (const Decl *Redecl = OffendingDecl-><wbr>getMostRecentDecl(); Redecl;<br>
          Redecl = Redecl->getPreviousDecl()) {<br>
       const AvailabilityAttr *AForRedecl = getAttrForPlatform(S.Context,<br>
                                                               Redecl);<br>
       if (AForRedecl && !AForRedecl->isInherited()) {<br>
         // If D is a declaration with inherited attributes, the note should<br>
         // point to the declaration with actual attributes.<br>
-        S.Diag(Redecl->getLocation(), diag_available_here) << D<br>
+        S.Diag(Redecl->getLocation(), diag_available_here) << OffendingDecl<br>
             << available_here_select_kind;<br>
         break;<br>
       }<br>
@@ -7095,10 +7123,19 @@ static void DoEmitAvailabilityWarning(Se<br>
   }<br>
   else<br>
     S.Diag(NoteLocation, diag_available_here)<br>
-        << D << available_here_select_kind;<br>
+        << OffendingDecl << available_here_select_kind;<br>
<br>
   if (K == AR_NotYetIntroduced)<br>
-    S.Diag(Loc, diag::note_partial_<wbr>availability_silence) << D;<br>
+    if (const auto *Enclosing = findEnclosingDeclToAnnotate(<wbr>Ctx)) {<br>
+      if (auto *TD = dyn_cast<TagDecl>(Enclosing))<br>
+        if (TD->getDeclName().isEmpty()) {<br>
+          S.Diag(TD->getLocation(), diag::note_partial_<wbr>availability_silence)<br>
+              << /*Anonymous*/1 << TD->getKindName();<br>
+          return;<br>
+        }<br>
+      S.Diag(Enclosing->getLocation(<wbr>), diag::note_partial_<wbr>availability_silence)<br>
+          << /*Named*/0 << Enclosing;<br>
+    }<br>
 }<br>
<br>
 static void handleDelayedAvailabilityCheck<wbr>(Sema &S, DelayedDiagnostic &DD,<br>
@@ -7108,9 +7145,9 @@ static void handleDelayedAvailabilityChe<br>
<br>
   DD.Triggered = true;<br>
   DoEmitAvailabilityWarning(<br>
-      S, DD.getAvailabilityResult(), Ctx, DD.getAvailabilityDecl(),<br>
-      DD.getAvailabilityMessage(), DD.Loc, DD.getUnknownObjCClass(),<br>
-      DD.getObjCProperty(), false);<br>
+      S, DD.getAvailabilityResult(), Ctx, DD.<wbr>getAvailabilityReferringDecl()<wbr>,<br>
+      DD.<wbr>getAvailabilityOffendingDecl()<wbr>, DD.getAvailabilityMessage(), DD.Loc,<br>
+      DD.getUnknownObjCClass(), DD.getObjCProperty(), false);<br>
 }<br>
<br>
 void Sema::PopParsingDeclaration(<wbr>ParsingDeclState state, Decl *decl) {<br>
@@ -7169,22 +7206,25 @@ void Sema::redelayDiagnostics(<wbr>DelayedDia<br>
 }<br>
<br>
 void Sema::EmitAvailabilityWarning(<wbr>AvailabilityResult AR,<br>
-                                   NamedDecl *D, StringRef Message,<br>
-                                   SourceLocation Loc,<br>
+                                   const NamedDecl *ReferringDecl,<br>
+                                   const NamedDecl *OffendingDecl,<br>
+                                   StringRef Message, SourceLocation Loc,<br>
                                    const ObjCInterfaceDecl *UnknownObjCClass,<br>
-                                   const ObjCPropertyDecl  *ObjCProperty,<br>
+                                   const ObjCPropertyDecl *ObjCProperty,<br>
                                    bool ObjCPropertyAccess) {<br>
   // Delay if we're currently parsing a declaration.<br>
   if (DelayedDiagnostics.<wbr>shouldDelayDiagnostics()) {<br>
-    DelayedDiagnostics.add(<wbr>DelayedDiagnostic::<wbr>makeAvailability(<br>
-        AR, Loc, D, UnknownObjCClass, ObjCProperty, Message,<br>
-        ObjCPropertyAccess));<br>
+    DelayedDiagnostics.add(<br>
+        DelayedDiagnostic::<wbr>makeAvailability(<br>
+            AR, Loc, ReferringDecl, OffendingDecl, UnknownObjCClass,<br>
+            ObjCProperty, Message, ObjCPropertyAccess));<br>
     return;<br>
   }<br>
<br>
   Decl *Ctx = cast<Decl>(<wbr>getCurLexicalContext());<br>
-  DoEmitAvailabilityWarning(*<wbr>this, AR, Ctx, D, Message, Loc, UnknownObjCClass,<br>
-                            ObjCProperty, ObjCPropertyAccess);<br>
+  DoEmitAvailabilityWarning(*<wbr>this, AR, Ctx, ReferringDecl, OffendingDecl,<br>
+                            Message, Loc, UnknownObjCClass, ObjCProperty,<br>
+                            ObjCPropertyAccess);<br>
 }<br>
<br>
 namespace {<br>
@@ -7336,19 +7376,21 @@ public:<br>
<br>
 void DiagnoseUnguardedAvailability:<wbr>:DiagnoseDeclAvailability(<br>
     NamedDecl *D, SourceRange Range) {<br>
-<br>
-  VersionTuple ContextVersion = AvailabilityStack.back();<br>
-  if (AvailabilityResult Result =<br>
-          SemaRef.<wbr>ShouldDiagnoseAvailabilityOfDe<wbr>cl(D, nullptr)) {<br>
+  AvailabilityResult Result;<br>
+  const NamedDecl *OffendingDecl;<br>
+  std::tie(Result, OffendingDecl) =<br>
+      SemaRef.<wbr>ShouldDiagnoseAvailabilityOfDe<wbr>cl(D, nullptr);<br>
+  if (Result != AR_Available) {<br>
     // All other diagnostic kinds have already been handled in<br>
     // DiagnoseAvailabilityOfDecl.<br>
     if (Result != AR_NotYetIntroduced)<br>
       return;<br>
<br>
-    const AvailabilityAttr *AA = getAttrForPlatform(SemaRef.<wbr>getASTContext(), D);<br>
+    const AvailabilityAttr *AA =<br>
+      getAttrForPlatform(SemaRef.<wbr>getASTContext(), OffendingDecl);<br>
     VersionTuple Introduced = AA->getIntroduced();<br>
<br>
-    if (ContextVersion >= Introduced)<br>
+    if (AvailabilityStack.back() >= Introduced)<br>
       return;<br>
<br>
     // If the context of this function is less available than D, we should not<br>
@@ -7373,8 +7415,9 @@ void DiagnoseUnguardedAvailability:<wbr>:Diag<br>
                SemaRef.getASTContext().<wbr>getTargetInfo().<wbr>getPlatformName())<br>
         << Introduced.getAsString();<br>
<br>
-    SemaRef.Diag(D->getLocation(), diag::note_availability_<wbr>specified_here)<br>
-        << D << /* partial */ 3;<br>
+    SemaRef.Diag(OffendingDecl-><wbr>getLocation(),<br>
+                 diag::note_availability_<wbr>specified_here)<br>
+        << OffendingDecl << /* partial */ 3;<br>
<br>
     auto FixitDiag =<br>
         SemaRef.Diag(Range.getBegin(), diag::note_unguarded_<wbr>available_silence)<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=307175&r1=307174&r2=307175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaExpr.cpp?rev=307175&r1=<wbr>307174&r2=307175&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp Wed Jul  5 10:08:56 2017<br>
@@ -87,24 +87,9 @@ static void DiagnoseUnusedOfDecl(Sema &S<br>
   }<br>
 }<br>
<br>
-static bool HasRedeclarationWithoutAvailab<wbr>ilityInCategory(const Decl *D) {<br>
-  const auto *OMD = dyn_cast<ObjCMethodDecl>(D);<br>
-  if (!OMD)<br>
-    return false;<br>
-  const ObjCInterfaceDecl *OID = OMD->getClassInterface();<br>
-  if (!OID)<br>
-    return false;<br>
-<br>
-  for (const ObjCCategoryDecl *Cat : OID->visible_categories())<br>
-    if (ObjCMethodDecl *CatMeth =<br>
-            Cat->getMethod(OMD-><wbr>getSelector(), OMD->isInstanceMethod()))<br>
-      if (!CatMeth->hasAttr<<wbr>AvailabilityAttr>())<br>
-        return true;<br>
-  return false;<br>
-}<br>
-<br>
-AvailabilityResult<br>
-Sema::<wbr>ShouldDiagnoseAvailabilityOfDe<wbr>cl(NamedDecl *&D, std::string *Message) {<br>
+std::pair<AvailabilityResult, const NamedDecl *><br>
+Sema::<wbr>ShouldDiagnoseAvailabilityOfDe<wbr>cl(const NamedDecl *D,<br>
+                                       std::string *Message) {<br>
   AvailabilityResult Result = D->getAvailability(Message);<br>
<br>
   // For typedefs, if the typedef declaration appears available look<br>
@@ -121,45 +106,23 @@ Sema::<wbr>ShouldDiagnoseAvailabilityOfDe<wbr>cl(N<br>
   }<br>
<br>
   // Forward class declarations get their attributes from their definition.<br>
-  if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(D)<wbr>) {<br>
+  if (const ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(D)<wbr>) {<br>
     if (IDecl->getDefinition()) {<br>
       D = IDecl->getDefinition();<br>
       Result = D->getAvailability(Message);<br>
     }<br>
   }<br>
<br>
-  if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))<br>
+  if (const auto *ECD = dyn_cast<EnumConstantDecl>(D))<br>
     if (Result == AR_Available) {<br>
       const DeclContext *DC = ECD->getDeclContext();<br>
-      if (const EnumDecl *TheEnumDecl = dyn_cast<EnumDecl>(DC))<br>
+      if (const auto *TheEnumDecl = dyn_cast<EnumDecl>(DC)) {<br>
         Result = TheEnumDecl->getAvailability(<wbr>Message);<br>
+        D = TheEnumDecl;<br>
+      }<br>
     }<br>
<br>
-  if (Result == AR_NotYetIntroduced) {<br>
-    // Don't do this for enums, they can't be redeclared.<br>
-    if (isa<EnumConstantDecl>(D) || isa<EnumDecl>(D))<br>
-      return AR_Available;<br>
-<br>
-    bool Warn = !D->getAttr<AvailabilityAttr>(<wbr>)->isInherited();<br>
-    // Objective-C method declarations in categories are not modelled as<br>
-    // redeclarations, so manually look for a redeclaration in a category<br>
-    // if necessary.<br>
-    if (Warn && HasRedeclarationWithoutAvailab<wbr>ilityInCategory(D))<br>
-      Warn = false;<br>
-    // In general, D will point to the most recent redeclaration. However,<br>
-    // for `@class A;` decls, this isn't true -- manually go through the<br>
-    // redecl chain in that case.<br>
-    if (Warn && isa<ObjCInterfaceDecl>(D))<br>
-      for (Decl *Redecl = D->getMostRecentDecl(); Redecl && Warn;<br>
-           Redecl = Redecl->getPreviousDecl())<br>
-        if (!Redecl->hasAttr<<wbr>AvailabilityAttr>() ||<br>
-            Redecl->getAttr<<wbr>AvailabilityAttr>()-><wbr>isInherited())<br>
-          Warn = false;<br>
-<br>
-    return Warn ? AR_NotYetIntroduced : AR_Available;<br>
-  }<br>
-<br>
-  return Result;<br>
+  return {Result, D};<br>
 }<br>
<br>
 static void<br>
@@ -167,32 +130,34 @@ DiagnoseAvailabilityOfDecl(<wbr>Sema &S, Name<br>
                            const ObjCInterfaceDecl *UnknownObjCClass,<br>
                            bool ObjCPropertyAccess) {<br>
   std::string Message;<br>
+  AvailabilityResult Result;<br>
+  const NamedDecl* OffendingDecl;<br>
   // See if this declaration is unavailable, deprecated, or partial.<br>
-  if (AvailabilityResult Result =<br>
-          S.<wbr>ShouldDiagnoseAvailabilityOfDe<wbr>cl(D, &Message)) {<br>
+  std::tie(Result, OffendingDecl) = S.<wbr>ShouldDiagnoseAvailabilityOfDe<wbr>cl(D, &Message);<br>
+  if (Result == AR_Available)<br>
+    return;<br>
<br>
-    if (Result == AR_NotYetIntroduced) {<br>
-      if (S.getCurFunctionOrMethodDecl(<wbr>)) {<br>
-        S.getEnclosingFunction()-><wbr>HasPotentialAvailabilityViolat<wbr>ions = true;<br>
-        return;<br>
-      } else if (S.getCurBlock() || S.getCurLambda()) {<br>
-        S.getCurFunction()-><wbr>HasPotentialAvailabilityViolat<wbr>ions = true;<br>
-        return;<br>
-      }<br>
+  if (Result == AR_NotYetIntroduced) {<br>
+    if (S.getCurFunctionOrMethodDecl(<wbr>)) {<br>
+      S.getEnclosingFunction()-><wbr>HasPotentialAvailabilityViolat<wbr>ions = true;<br>
+      return;<br>
+    } else if (S.getCurBlock() || S.getCurLambda()) {<br>
+      S.getCurFunction()-><wbr>HasPotentialAvailabilityViolat<wbr>ions = true;<br>
+      return;<br>
     }<br>
+  }<br>
<br>
-    const ObjCPropertyDecl *ObjCPDecl = nullptr;<br>
-    if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {<br>
-      if (const ObjCPropertyDecl *PD = MD->findPropertyDecl()) {<br>
-        AvailabilityResult PDeclResult = PD->getAvailability(nullptr);<br>
-        if (PDeclResult == Result)<br>
-          ObjCPDecl = PD;<br>
-      }<br>
+  const ObjCPropertyDecl *ObjCPDecl = nullptr;<br>
+  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {<br>
+    if (const ObjCPropertyDecl *PD = MD->findPropertyDecl()) {<br>
+      AvailabilityResult PDeclResult = PD->getAvailability(nullptr);<br>
+      if (PDeclResult == Result)<br>
+        ObjCPDecl = PD;<br>
     }<br>
-<br>
-    S.EmitAvailabilityWarning(<wbr>Result, D, Message, Loc, UnknownObjCClass,<br>
-                              ObjCPDecl, ObjCPropertyAccess);<br>
   }<br>
+<br>
+  S.EmitAvailabilityWarning(<wbr>Result, D, OffendingDecl, Message, Loc,<br>
+                            UnknownObjCClass, ObjCPDecl, ObjCPropertyAccess);<br>
 }<br>
<br>
 /// \brief Emit a note explaining that this function is deleted.<br>
<br>
Modified: cfe/trunk/test/Sema/attr-<wbr>availability.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-availability.c?rev=307175&r1=307174&r2=307175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/Sema/<wbr>attr-availability.c?rev=<wbr>307175&r1=307174&r2=307175&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Sema/attr-<wbr>availability.c (original)<br>
+++ cfe/trunk/test/Sema/attr-<wbr>availability.c Wed Jul  5 10:08:56 2017<br>
@@ -21,6 +21,9 @@ ATSFontGetPostScriptName(int flags) __at<br>
 extern void<br>
 PartiallyAvailable() __attribute__((availability(<wbr>macosx,introduced=10.8)));<br>
<br>
+#ifdef WARN_PARTIAL<br>
+// expected-note@+2 2 {{marked partial here}}<br>
+#endif<br>
 enum __attribute__((availability(<wbr>macosx,introduced=10.8))) PartialEnum {<br>
   kPartialEnumConstant,<br>
 };<br>
@@ -35,11 +38,19 @@ void test_10095131() {<br>
   PartiallyAvailable();<br>
 }<br>
<br>
+#ifdef WARN_PARTIAL<br>
+// FIXME: This note should point to the declaration with the availability<br>
+// attribute.<br>
+// expected-note@+2 {{marked partial here}}<br>
+#endif<br>
 extern void PartiallyAvailable() ;<br>
 void with_redeclaration() {<br>
-  PartiallyAvailable();  // Don't warn.<br>
-<br>
-  // enums should never warn.<br>
+#ifdef WARN_PARTIAL<br>
+  // expected-warning@+4 {{'PartiallyAvailable' is only available on macOS 10.8 or newer}} expected-note@+4 {{__builtin_available}}<br>
+  // expected-warning@+4 {{'PartialEnum' is only available on macOS 10.8 or newer}} expected-note@+4 {{__builtin_available}}<br>
+  // expected-warning@+3 {{'kPartialEnumConstant' is only available on macOS 10.8 or newer}} expected-note@+3 {{__builtin_available}}<br>
+#endif<br>
+  PartiallyAvailable();<br>
   enum PartialEnum p = kPartialEnumConstant;<br>
 }<br>
<br>
@@ -86,13 +97,13 @@ enum Original {<br>
   OriginalUnavailable __attribute__((availability(<wbr>macosx, unavailable))) // expected-note + {{'OriginalUnavailable' has been explicitly marked unavailable here}}<br>
 };<br>
<br>
-enum AllDeprecated {<br>
-  AllDeprecatedCase, // expected-note + {{'AllDeprecatedCase' has been explicitly marked deprecated here}}<br>
+enum AllDeprecated { // expected-note + {{'AllDeprecated' has been explicitly marked deprecated here}}<br>
+  AllDeprecatedCase,<br>
   AllDeprecatedUnavailable __attribute__((availability(<wbr>macosx, unavailable))) // expected-note + {{'AllDeprecatedUnavailable' has been explicitly marked unavailable here}}<br>
 } __attribute__((availability(<wbr>macosx, deprecated=10.2)));<br>
<br>
-enum AllUnavailable {<br>
-  AllUnavailableCase, // expected-note + {{'AllUnavailableCase' has been explicitly marked unavailable here}}<br>
+enum AllUnavailable { // expected-note + {{'AllUnavailable' has been explicitly marked unavailable here}}<br>
+  AllUnavailableCase,<br>
 } __attribute__((availability(<wbr>macosx, unavailable)));<br>
<br>
 enum User {<br>
<br>
Modified: cfe/trunk/test/Sema/attr-<wbr>deprecated.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-deprecated.c?rev=307175&r1=307174&r2=307175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/Sema/<wbr>attr-deprecated.c?rev=307175&<wbr>r1=307174&r2=307175&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Sema/attr-<wbr>deprecated.c (original)<br>
+++ cfe/trunk/test/Sema/attr-<wbr>deprecated.c Wed Jul  5 10:08:56 2017<br>
@@ -104,9 +104,9 @@ foo_dep test17, // expected-warning {{'f<br>
         test19;<br>
<br>
 // rdar://problem/8518751<br>
-enum __attribute__((deprecated)) Test20 { // expected-note {{'Test20' has been explicitly marked deprecated here}}<br>
+enum __attribute__((deprecated)) Test20 { // expected-note 2 {{'Test20' has been explicitly marked deprecated here}}<br>
   test20_a __attribute__((deprecated)), // expected-note {{'test20_a' has been explicitly marked deprecated here}}<br>
-  test20_b // expected-note {{'test20_b' has been explicitly marked deprecated here}}<br>
+  test20_b<br>
 };<br>
 void test20() {<br>
   enum Test20 f; // expected-warning {{'Test20' is deprecated}}<br>
<br>
Modified: cfe/trunk/test/Sema/attr-<wbr>unavailable-message.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-unavailable-message.c?rev=307175&r1=307174&r2=307175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/Sema/<wbr>attr-unavailable-message.c?<wbr>rev=307175&r1=307174&r2=<wbr>307175&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Sema/attr-<wbr>unavailable-message.c (original)<br>
+++ cfe/trunk/test/Sema/attr-<wbr>unavailable-message.c Wed Jul  5 10:08:56 2017<br>
@@ -36,13 +36,13 @@ void unavail(void) {<br>
<br>
 // rdar://10201690<br>
 enum foo {<br>
-    a = 1, // expected-note {{'a' has been explicitly marked deprecated here}}<br>
+    a = 1,<br>
     b __attribute__((deprecated())) = 2, // expected-note {{'b' has been explicitly marked deprecated here}}<br>
     c = 3<br>
-}__attribute__((deprecated())<wbr>);<br>
+}__attribute__((deprecated())<wbr>); // expected-note {{'foo' has been explicitly marked deprecated here}}<br>
<br>
-enum fee { // expected-note {{'fee' has been explicitly marked unavailable here}}<br>
-    r = 1, // expected-note {{'r' has been explicitly marked unavailable here}}<br>
+enum fee { // expected-note 2 {{'fee' has been explicitly marked unavailable here}}<br>
+    r = 1,<br>
     s = 2,<br>
     t = 3<br>
 }__attribute__((unavailable())<wbr>);<br>
<br>
Modified: cfe/trunk/test/SemaCXX/attr-<wbr>deprecated.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-deprecated.cpp?rev=307175&r1=307174&r2=307175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaCXX/attr-deprecated.cpp?<wbr>rev=307175&r1=307174&r2=<wbr>307175&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaCXX/attr-<wbr>deprecated.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/attr-<wbr>deprecated.cpp Wed Jul  5 10:08:56 2017<br>
@@ -199,8 +199,8 @@ namespace test5 {<br>
<br>
 // rdar://problem/8518751<br>
 namespace test6 {<br>
-  enum __attribute__((deprecated)) A { // expected-note {{'A' has been explicitly marked deprecated here}}<br>
-    a0 // expected-note {{'a0' has been explicitly marked deprecated here}}<br>
+  enum __attribute__((deprecated)) A { // expected-note 2 {{'A' has been explicitly marked deprecated here}}<br>
+    a0<br>
   };<br>
   void testA() {<br>
     A x; // expected-warning {{'A' is deprecated}}<br>
@@ -218,8 +218,8 @@ namespace test6 {<br>
   }<br>
<br>
   template <class T> struct C {<br>
-    enum __attribute__((deprecated)) Enum { // expected-note {{'Enum' has been explicitly marked deprecated here}}<br>
-      c0 // expected-note {{'c0' has been explicitly marked deprecated here}}<br>
+    enum __attribute__((deprecated)) Enum { // expected-note 2 {{'Enum' has been explicitly marked deprecated here}}<br>
+      c0<br>
     };<br>
   };<br>
   void testC() {<br>
<br>
Modified: cfe/trunk/test/SemaObjC/attr-<wbr>availability.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-availability.m?rev=307175&r1=307174&r2=307175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaObjC/attr-availability.m?<wbr>rev=307175&r1=307174&r2=<wbr>307175&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaObjC/attr-<wbr>availability.m (original)<br>
+++ cfe/trunk/test/SemaObjC/attr-<wbr>availability.m Wed Jul  5 10:08:56 2017<br>
@@ -13,7 +13,7 @@<br>
 @interface A <P><br>
 - (void)method __attribute__((availability(<wbr>macosx,introduced=10.1,<wbr>deprecated=10.2))); // expected-note {{'method' has been explicitly marked deprecated here}}<br>
 #if defined(WARN_PARTIAL)<br>
-  // expected-note@+2 {{'partialMethod' has been explicitly marked partial here}}<br>
+  // expected-note@+2 2 {{'partialMethod' has been explicitly marked partial here}}<br>
 #endif<br>
 - (void)partialMethod __attribute__((availability(<wbr>macosx,introduced=10.8)));<br>
<br>
@@ -66,7 +66,10 @@ void f(A *a, B *b) {<br>
 @end<br>
<br>
 void f_after_redecl(A *a, B *b) {<br>
-  [a partialMethod]; // no warning<br>
+#ifdef WARN_PARTIAL<br>
+  // expected-warning@+2{{'<wbr>partialMethod' is only available on macOS 10.8 or newer}} expected-note@+2 {{@available}}<br>
+#endif<br>
+  [a partialMethod];<br>
   [b partialMethod]; // no warning<br>
   [a partial_proto_method]; // no warning<br>
   [b partial_proto_method]; // no warning<br>
@@ -133,6 +136,10 @@ id NSNibOwner, topNibObjects;<br>
 @end<br>
<br>
 @interface PartialI <PartialProt><br>
+#ifdef WARN_PARTIAL<br>
+// expected-note@+3{{marked partial here}}<br>
+// expected-note@+3{{marked partial here}}<br>
+#endif<br>
 - (void)partialMethod __attribute__((availability(<wbr>macosx,introduced=10.8)));<br>
 + (void)partialMethod __attribute__((availability(<wbr>macosx,introduced=10.8)));<br>
 @end<br>
@@ -160,14 +167,20 @@ id NSNibOwner, topNibObjects;<br>
 @end<br>
<br>
 void partialfun(PartialI* a) {<br>
-  [a partialMethod]; // no warning<br>
+#ifdef WARN_PARTIAL<br>
+  // expected-warning@+2 {{'partialMethod' is only available on macOS 10.8 or newer}} expected-note@+2{{@available}}<br>
+#endif<br>
+  [a partialMethod];<br>
   [a ipartialMethod1]; // no warning<br>
 #if defined(WARN_PARTIAL)<br>
   // expected-warning@+2 {{'ipartialMethod2' is only available on macOS 10.8 or newer}} expected-note@+2 {{enclose 'ipartialMethod2' in an @available check to silence this warning}}<br>
 #endif<br>
   [a ipartialMethod2];<br>
   [a ppartialMethod]; // no warning<br>
-  [PartialI partialMethod]; // no warning<br>
+#ifdef WARN_PARTIAL<br>
+  // expected-warning@+2 {{'partialMethod' is only available on macOS 10.8 or newer}} expected-note@+2 {{@available}}<br>
+#endif<br>
+  [PartialI partialMethod];<br>
   [PartialI ipartialMethod1]; // no warning<br>
 #if defined(WARN_PARTIAL)<br>
   // expected-warning@+2 {{'ipartialMethod2' is only available on macOS 10.8 or newer}} expected-note@+2 {{enclose 'ipartialMethod2' in an @available check to silence this warning}}<br>
@@ -177,20 +190,23 @@ void partialfun(PartialI* a) {<br>
 }<br>
<br>
 #if defined(WARN_PARTIAL)<br>
-  // expected-note@+2 {{'PartialI2' has been explicitly marked partial here}}<br>
+  // expected-note@+2 2 {{'PartialI2' has been explicitly marked partial here}}<br>
 #endif<br>
 __attribute__((availability(<wbr>macosx, introduced = 10.8))) @interface PartialI2<br>
 @end<br>
<br>
 #if defined(WARN_PARTIAL)<br>
-  // expected-warning@+2 {{'PartialI2' is partial: introduced in macOS 10.8}} expected-note@+2 {{explicitly redeclare 'PartialI2' to silence this warning}}<br>
+// expected-warning@+2 {{'PartialI2' is partial: introduced in macOS 10.8}} expected-note@+2 {{annotate 'partialinter1' with an availability attribute to silence}}<br>
 #endif<br>
 void partialinter1(PartialI2* p) {<br>
 }<br>
<br>
 @class PartialI2;<br>
<br>
-void partialinter2(PartialI2* p) { // no warning<br>
+#ifdef WARN_PARTIAL<br>
+// expected-warning@+2 {{'PartialI2' is partial: introduced in macOS 10.8}} expected-note@+2 {{annotate 'partialinter2' with an availability attribute to silence}}<br>
+#endif<br>
+void partialinter2(PartialI2* p) {<br>
 }<br>
<br>
<br>
<br>
Modified: cfe/trunk/test/SemaObjC/<wbr>unguarded-availability-new.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/unguarded-availability-new.m?rev=307175&r1=307174&r2=307175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaObjC/unguarded-<wbr>availability-new.m?rev=307175&<wbr>r1=307174&r2=307175&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaObjC/<wbr>unguarded-availability-new.m (original)<br>
+++ cfe/trunk/test/SemaObjC/<wbr>unguarded-availability-new.m Wed Jul  5 10:08:56 2017<br>
@@ -96,16 +96,16 @@ typedef int AVAILABLE_NEXT new_int;<br>
 FUNC_AVAILABLE new_int x;<br>
 #ifndef NO_WARNING<br>
 #ifdef MAC<br>
-  // expected-warning@-3 {{'new_int' is partial: introduced in macOS 10.14}} expected-note@-3 {{explicitly redeclare 'new_int' to silence this warning}}<br>
+  // expected-warning@-3 {{'new_int' is partial: introduced in macOS 10.14}} expected-note@-3 {{annotate 'x' with an availability attribute to silence}}<br>
 #endif<br>
 #ifdef IOS<br>
-  // expected-warning@-6 {{'new_int' is partial: introduced in iOS 12}} expected-note@-6 {{explicitly redeclare 'new_int' to silence this warning}}<br>
+  // expected-warning@-6 {{'new_int' is partial: introduced in iOS 12}} expected-note@-6 {{annotate 'x' with an availability attribute to silence}}<br>
 #endif<br>
 #ifdef TVOS<br>
-  // expected-warning@-9 {{'new_int' is partial: introduced in tvOS 13}} expected-note@-9 {{explicitly redeclare 'new_int' to silence this warning}}<br>
+  // expected-warning@-9 {{'new_int' is partial: introduced in tvOS 13}} expected-note@-9 {{annotate 'x' with an availability attribute to silence}}<br>
 #endif<br>
 #ifdef WATCHOS<br>
-  // expected-warning@-12 {{'new_int' is partial: introduced in watchOS 5}} expected-note@-12 {{explicitly redeclare 'new_int' to silence this warning}}<br>
+  // expected-warning@-12 {{'new_int' is partial: introduced in watchOS 5}} expected-note@-12 {{annotate 'x' with an availability attribute to silence}}<br>
 #endif<br>
 #endif<br>
<br>
<br>
Modified: cfe/trunk/test/SemaObjC/<wbr>unguarded-availability.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/unguarded-availability.m?rev=307175&r1=307174&r2=307175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaObjC/unguarded-<wbr>availability.m?rev=307175&r1=<wbr>307174&r2=307175&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaObjC/<wbr>unguarded-availability.m (original)<br>
+++ cfe/trunk/test/SemaObjC/<wbr>unguarded-availability.m Wed Jul  5 10:08:56 2017<br>
@@ -5,6 +5,8 @@<br>
 #define AVAILABLE_10_11 __attribute__((availability(<wbr>macos, introduced = 10.11)))<br>
 #define AVAILABLE_10_12 __attribute__((availability(<wbr>macos, introduced = 10.12)))<br>
<br>
+typedef int AVAILABLE_10_12 new_int; // expected-note + {{marked partial here}}<br>
+<br>
 int func_10_11() AVAILABLE_10_11; // expected-note 4 {{'func_10_11' has been explicitly marked partial here}}<br>
<br>
 #ifdef OBJCPP<br>
@@ -70,9 +72,9 @@ void use_typedef() {<br>
 }<br>
<br>
 __attribute__((objc_root_<wbr>class))<br>
-AVAILABLE_10_11 @interface Class_10_11 {<br>
+AVAILABLE_10_11 @interface Class_10_11 { // expected-note{{annotate 'Class_10_11' with an availability attribute to silence}}<br>
   int_10_11 foo;<br>
-  int_10_12 bar; // expected-warning {{'int_10_12' is partial: introduced in macOS 10.12}} expected-note{{redeclare}}<br>
+  int_10_12 bar; // expected-warning {{'int_10_12' is partial: introduced in macOS 10.12}}<br>
 }<br>
 - (void)method1;<br>
 - (void)method2;<br>
@@ -125,7 +127,7 @@ void test_blocks() {<br>
   };<br>
 }<br>
<br>
-void test_params(int_10_12 x); // expected-warning {{'int_10_12' is partial: introduced in macOS 10.12}} expected-note{{redeclare}}<br>
+void test_params(int_10_12 x); // expected-warning {{'int_10_12' is partial: introduced in macOS 10.12}} expected-note{{annotate 'test_params' with an availability attribute to silence}}<br>
<br>
 void test_params2(int_10_12 x) AVAILABLE_10_12; // no warn<br>
<br>
@@ -234,3 +236,30 @@ void functionInFunction() {<br>
 }<br>
<br>
 #endif<br>
+<br>
+struct InStruct { // expected-note{{annotate 'InStruct' with an availability attribute to silence}}<br>
+  new_int mem; // expected-warning{{'new_int' is partial}}<br>
+<br>
+  struct { new_int mem; } anon; // expected-warning{{'new_int' is partial}} expected-note{{annotate anonymous struct with an availability attribute}}<br>
+};<br>
+<br>
+#ifdef OBJCPP<br>
+static constexpr int AVAILABLE_10_12 SomeConstexprValue = 2; // expected-note{{marked partial here}}<br>
+typedef enum { // expected-note{{annotate anonymous enum with an availability attribute}}<br>
+  SomeValue = SomeConstexprValue // expected-warning{{'<wbr>SomeConstexprValue' is partial}}<br>
+} SomeEnum;<br>
+#endif<br>
+<br>
+@interface InInterface<br>
+-(new_int)meth; // expected-warning{{'new_int' is partial}} expected-note{{annotate 'meth' with an availability attribute}}<br>
+@end<br>
+<br>
+@interface Proper // expected-note{{annotate 'Proper' with an availability attribute}}<br>
+@property (class) new_int x; // expected-warning{{'new_int' is partial}}<br>
+@end<br>
+<br>
+void with_local_struct() {<br>
+  struct local { // expected-note{{annotate 'local' with an availability attribute}}<br>
+    new_int x; // expected-warning{{'new_int' is partial}}<br>
+  };<br>
+}<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>