Yes. I filed rdar://problem/28812809 <rdar://problem/28812809> to report that 
problem in the SDK. I also filed rdar://problem/28825862 
<rdar://problem/28825862> to remind us to restore the more strict checking 
after we release a version of the tvOS SDK with a fix.

Thanks, Erik!

> On Oct 18, 2016, at 9:46 AM, Erik Pilkington <erik.pilking...@gmail.com> 
> wrote:
> 
> 
> On second thought, I think the header *is* ill-formed here. If we allowed 
> this behaviour, this would provide a way to circumvent an availability 
> diagnostic. For example, now the following compiles cleanly, where we really 
> should emit a diagnostic somewhere!
> 
> typedef int unavail_int __attribute__((availability(tvos, unavailable)));
> 
> __attribute__((availability(tvos, unavailable)))
> @interface A
> extern unavail_int foo;
> @end
> 
> int main() { (void)foo; }
> 
> I’m not so sure about the politics of this, but could you file a radar or 
> something to get the header fixed (i.e, make the variable __TVOS_PROHIBITED)? 
> I’ll make a new patch that makes this a special case for now.
> 
> Sorry for the flip-flop!
> Erik
> 
>> On Oct 18, 2016, at 11:47 AM, Erik Pilkington <erik.pilking...@gmail.com 
>> <mailto:erik.pilking...@gmail.com>> wrote:
>> 
>> Hi Bob,
>> I think the code in the header is fine here, so I reverted in r284486. 
>> Here’s a reduced version:
>> 
>> typedef int unavail_int __attribute__((availability(tvos, unavailable)));
>> 
>> __attribute__((availability(tvos, unavailable)))
>> @interface A
>> extern unavail_int foo;
>> @end
>> 
>> The problem is that ‘foo’ is actually at file context, not in the context of 
>> the interface, because we temporarily switched contexts to parse it. This 
>> means we can’t just look at DeclContexts in the DelayedDiagnostic case, 
>> which is what I was doing here. I’ll try to get a fix out for this soon!
>> 
>> Thanks for pointing this out!
>> Erik
>> 
>>> On Oct 18, 2016, at 1:37 AM, Bob Wilson <bob.wil...@apple.com 
>>> <mailto:bob.wil...@apple.com>> wrote:
>>> 
>>> Hi Erik,
>>> 
>>> This change does not work with one of the headers from the AVFoundation 
>>> framework in tvOS 10.0. We can try to get a fix into the tvOS SDK, but it 
>>> will probably be a while before we could release an SDK with that change. 
>>> In the meantime, this is kind of disruptive. Can you find a way to keep the 
>>> previous behavior, at least until we have a chance to fix that header?
>>> 
>>> The header in question is 
>>> System/Library/Frameworks/AVFoundation.framework/Headers/AVCaptureDevice.h 
>>> in the AppleTVSimulator.sdk directory from Xcode 8.0. The problematic 
>>> declaration is this one:
>>> 
>>> AVF_EXPORT const AVCaptureWhiteBalanceGains 
>>> AVCaptureWhiteBalanceGainsCurrent NS_AVAILABLE_IOS(8_0);
>>> 
>>> The problem is that the type is declared like this:
>>> 
>>> typedef struct {
>>>    float redGain;
>>>    float greenGain;
>>>    float blueGain;
>>> } AVCaptureWhiteBalanceGains NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED;
>>> 
>>> The variable is missing the __TVOS_PROHIBITED attribute. You can reproduce 
>>> this easily:
>>> 
>>> $ cat t.m
>>> #import <AVFoundation/AVFoundation.h>
>>> $ clang -c -arch x86_64 -mtvos-simulator-version-min=10.0 -isysroot 
>>> /Applications/Xcode-8.0.app/Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/SDKs/AppleTVSimulator.sdk
>>>  t.m
>>> /Applications/Xcode-8.0.app/Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/SDKs/AppleTVSimulator.sdk/System/Library/Frameworks/AVFoundation.framework/Headers/AVCaptureDevice.h:1184:14:
>>>  error: 
>>>      'AVCaptureWhiteBalanceGains' is unavailable: not available on tvOS
>>> extern const AVCaptureWhiteBalanceGains AVCaptureWhiteBalanceGainsCurren...
>>>             ^
>>> /Applications/Xcode-8.0.app/Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/SDKs/AppleTVSimulator.sdk/System/Library/Frameworks/AVFoundation.framework/Headers/AVCaptureDevice.h:1081:3:
>>>  note: 
>>>      'AVCaptureWhiteBalanceGains' has been explicitly marked unavailable 
>>> here
>>> } AVCaptureWhiteBalanceGains __attribute__((availability(ios,introduced=...
>>>  ^
>>> 1 error generated.
>>> 
>>> Maybe we can carve out an exception based on the fact that this is just an 
>>> extern declaration of the variable — it’s not actually being used here. It 
>>> is also defined within the @interface for an Objective-C class, in case 
>>> that helps at all.
>>> 
>>>> On Oct 14, 2016, at 12:08 PM, Erik Pilkington via cfe-commits 
>>>> <cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org>> wrote:
>>>> 
>>>> Author: epilk
>>>> Date: Fri Oct 14 14:08:01 2016
>>>> New Revision: 284265
>>>> 
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=284265&view=rev 
>>>> <http://llvm.org/viewvc/llvm-project?rev=284265&view=rev>
>>>> Log:
>>>> [Sema] Refactor context checking for availability diagnostics
>>>> 
>>>> This commit combines a couple of redundant functions that do availability
>>>> attribute context checking into a more correct/simpler one.
>>>> 
>>>> Differential revision: https://reviews.llvm.org/D25283 
>>>> <https://reviews.llvm.org/D25283>
>>>> 
>>>> Modified:
>>>>   cfe/trunk/include/clang/Sema/Sema.h
>>>>   cfe/trunk/lib/Sema/SemaDecl.cpp
>>>>   cfe/trunk/lib/Sema/SemaDeclAttr.cpp
>>>>   cfe/trunk/lib/Sema/SemaExpr.cpp
>>>>   cfe/trunk/test/SemaObjC/class-unavail-warning.m
>>>> 
>>>> Modified: cfe/trunk/include/clang/Sema/Sema.h
>>>> URL: 
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=284265&r1=284264&r2=284265&view=diff
>>>>  
>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=284265&r1=284264&r2=284265&view=diff>
>>>> ==============================================================================
>>>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>>>> +++ cfe/trunk/include/clang/Sema/Sema.h Fri Oct 14 14:08:01 2016
>>>> @@ -9889,23 +9889,16 @@ public:
>>>>    return OriginalLexicalContext ? OriginalLexicalContext : CurContext;
>>>>  }
>>>> 
>>>> -  AvailabilityResult getCurContextAvailability() const;
>>>> -
>>>> -  /// \brief Get the verison that this context implies.
>>>> -  /// For instance, a method in an interface that is annotated with an
>>>> -  /// availability attribuite effectively has the availability of the 
>>>> interface.
>>>> -  VersionTuple getVersionForDecl(const Decl *Ctx) const;
>>>> -
>>>>  /// \brief The diagnostic we should emit for \c D, or \c AR_Available.
>>>>  ///
>>>>  /// \param D The declaration to check. Note that this may be altered to 
>>>> point
>>>>  /// to another declaration that \c D gets it's availability from. i.e., we
>>>>  /// walk the list of typedefs to find an availability attribute.
>>>>  ///
>>>> -  /// \param ContextVersion The version to compare availability against.
>>>> -  AvailabilityResult
>>>> -  ShouldDiagnoseAvailabilityOfDecl(NamedDecl *&D, VersionTuple 
>>>> ContextVersion,
>>>> -                                   std::string *Message);
>>>> +  /// \param Message If non-null, this will be populated with the message 
>>>> from
>>>> +  /// the availability attribute that is selected.
>>>> +  AvailabilityResult ShouldDiagnoseAvailabilityOfDecl(NamedDecl *&D,
>>>> +                                                      std::string 
>>>> *Message);
>>>> 
>>>>  const DeclContext *getCurObjCLexicalContext() const {
>>>>    const DeclContext *DC = getCurLexicalContext();
>>>> 
>>>> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
>>>> URL: 
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=284265&r1=284264&r2=284265&view=diff
>>>>  
>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=284265&r1=284264&r2=284265&view=diff>
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
>>>> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Oct 14 14:08:01 2016
>>>> @@ -15615,29 +15615,3 @@ void Sema::ActOnPragmaWeakAlias(Identifi
>>>> Decl *Sema::getObjCDeclContext() const {
>>>>  return (dyn_cast_or_null<ObjCContainerDecl>(CurContext));
>>>> }
>>>> -
>>>> -AvailabilityResult Sema::getCurContextAvailability() const {
>>>> -  const Decl *D = cast_or_null<Decl>(getCurObjCLexicalContext());
>>>> -  if (!D)
>>>> -    return AR_Available;
>>>> -
>>>> -  // If we are within an Objective-C method, we should consult
>>>> -  // both the availability of the method as well as the
>>>> -  // enclosing class.  If the class is (say) deprecated,
>>>> -  // the entire method is considered deprecated from the
>>>> -  // purpose of checking if the current context is deprecated.
>>>> -  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
>>>> -    AvailabilityResult R = MD->getAvailability();
>>>> -    if (R != AR_Available)
>>>> -      return R;
>>>> -    D = MD->getClassInterface();
>>>> -  }
>>>> -  // If we are within an Objective-c @implementation, it
>>>> -  // gets the same availability context as the @interface.
>>>> -  else if (const ObjCImplementationDecl *ID =
>>>> -            dyn_cast<ObjCImplementationDecl>(D)) {
>>>> -    D = ID->getClassInterface();
>>>> -  }
>>>> -  // Recover from user error.
>>>> -  return D ? D->getAvailability() : AR_Available;
>>>> -}
>>>> 
>>>> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
>>>> URL: 
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=284265&r1=284264&r2=284265&view=diff
>>>>  
>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=284265&r1=284264&r2=284265&view=diff>
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
>>>> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Oct 14 14:08:01 2016
>>>> @@ -6317,30 +6317,6 @@ static void handleDelayedForbiddenType(S
>>>>  diag.Triggered = true;
>>>> }
>>>> 
>>>> -static bool isDeclDeprecated(Decl *D) {
>>>> -  do {
>>>> -    if (D->isDeprecated())
>>>> -      return true;
>>>> -    // A category implicitly has the availability of the interface.
>>>> -    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
>>>> -      if (const ObjCInterfaceDecl *Interface = CatD->getClassInterface())
>>>> -        return Interface->isDeprecated();
>>>> -  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
>>>> -  return false;
>>>> -}
>>>> -
>>>> -static bool isDeclUnavailable(Decl *D) {
>>>> -  do {
>>>> -    if (D->isUnavailable())
>>>> -      return true;
>>>> -    // A category implicitly has the availability of the interface.
>>>> -    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
>>>> -      if (const ObjCInterfaceDecl *Interface = CatD->getClassInterface())
>>>> -        return Interface->isUnavailable();
>>>> -  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
>>>> -  return false;
>>>> -}
>>>> -
>>>> static const AvailabilityAttr *getAttrForPlatform(ASTContext &Context,
>>>>                                                  const Decl *D) {
>>>>  // Check each AvailabilityAttr to find the one for this platform.
>>>> @@ -6369,6 +6345,49 @@ static const AvailabilityAttr *getAttrFo
>>>>  return nullptr;
>>>> }
>>>> 
>>>> +/// \brief whether we should emit a diagnostic for \c K and \c 
>>>> DeclVersion in
>>>> +/// the context of \c Ctx. For example, we should emit an unavailable 
>>>> diagnostic
>>>> +/// in a deprecated context, but not the other way around.
>>>> +static bool ShouldDiagnoseAvailabilityInContext(Sema &S, 
>>>> AvailabilityResult K,
>>>> +                                                VersionTuple DeclVersion,
>>>> +                                                Decl *Ctx) {
>>>> +  assert(K != AR_Available && "Expected an unavailable declaration 
>>>> here!");
>>>> +
>>>> +  // Checks if we should emit the availability diagnostic in the context 
>>>> of C.
>>>> +  auto CheckContext = [&](const Decl *C) {
>>>> +    if (K == AR_NotYetIntroduced) {
>>>> +      if (const AvailabilityAttr *AA = getAttrForPlatform(S.Context, C))
>>>> +        if (AA->getIntroduced() >= DeclVersion)
>>>> +          return true;
>>>> +    } else if (K == AR_Deprecated)
>>>> +      if (C->isDeprecated())
>>>> +        return true;
>>>> +
>>>> +    if (C->isUnavailable())
>>>> +      return true;
>>>> +    return false;
>>>> +  };
>>>> +
>>>> +  do {
>>>> +    if (CheckContext(Ctx))
>>>> +      return false;
>>>> +
>>>> +    // An implementation implicitly has the availability of the interface.
>>>> +    if (auto *CatOrImpl = dyn_cast<ObjCImplDecl>(Ctx)) {
>>>> +      if (const ObjCInterfaceDecl *Interface = 
>>>> CatOrImpl->getClassInterface())
>>>> +        if (CheckContext(Interface))
>>>> +          return false;
>>>> +    }
>>>> +    // A category implicitly has the availability of the interface.
>>>> +    else if (auto *CatD = dyn_cast<ObjCCategoryDecl>(Ctx))
>>>> +      if (const ObjCInterfaceDecl *Interface = CatD->getClassInterface())
>>>> +        if (CheckContext(Interface))
>>>> +          return false;
>>>> +  } while ((Ctx = cast_or_null<Decl>(Ctx->getDeclContext())));
>>>> +
>>>> +  return true;
>>>> +}
>>>> +
>>>> static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
>>>>                                      Decl *Ctx, const NamedDecl *D,
>>>>                                      StringRef Message, SourceLocation Loc,
>>>> @@ -6385,11 +6404,15 @@ static void DoEmitAvailabilityWarning(Se
>>>>  // Matches diag::note_availability_specified_here.
>>>>  unsigned available_here_select_kind;
>>>> 
>>>> -  // Don't warn if our current context is deprecated or unavailable.
>>>> +  VersionTuple DeclVersion;
>>>> +  if (const AvailabilityAttr *AA = getAttrForPlatform(S.Context, D))
>>>> +    DeclVersion = AA->getIntroduced();
>>>> +
>>>> +  if (!ShouldDiagnoseAvailabilityInContext(S, K, DeclVersion, Ctx))
>>>> +    return;
>>>> +
>>>>  switch (K) {
>>>>  case AR_Deprecated:
>>>> -    if (isDeclDeprecated(Ctx) || isDeclUnavailable(Ctx))
>>>> -      return;
>>>>    diag = !ObjCPropertyAccess ? diag::warn_deprecated
>>>>                               : diag::warn_property_method_deprecated;
>>>>    diag_message = diag::warn_deprecated_message;
>>>> @@ -6399,8 +6422,6 @@ static void DoEmitAvailabilityWarning(Se
>>>>    break;
>>>> 
>>>>  case AR_Unavailable:
>>>> -    if (isDeclUnavailable(Ctx))
>>>> -      return;
>>>>    diag = !ObjCPropertyAccess ? diag::err_unavailable
>>>>                               : diag::err_property_method_unavailable;
>>>>    diag_message = diag::err_unavailable_message;
>>>> @@ -6615,29 +6636,6 @@ void Sema::EmitAvailabilityWarning(Avail
>>>>                            ObjCProperty, ObjCPropertyAccess);
>>>> }
>>>> 
>>>> -VersionTuple Sema::getVersionForDecl(const Decl *D) const {
>>>> -  assert(D && "Expected a declaration here!");
>>>> -
>>>> -  VersionTuple DeclVersion;
>>>> -  if (const auto *AA = getAttrForPlatform(getASTContext(), D))
>>>> -    DeclVersion = AA->getIntroduced();
>>>> -
>>>> -  const ObjCInterfaceDecl *Interface = nullptr;
>>>> -
>>>> -  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
>>>> -    Interface = MD->getClassInterface();
>>>> -  else if (const auto *ID = dyn_cast<ObjCImplementationDecl>(D))
>>>> -    Interface = ID->getClassInterface();
>>>> -
>>>> -  if (Interface) {
>>>> -    if (const auto *AA = getAttrForPlatform(getASTContext(), Interface))
>>>> -      if (AA->getIntroduced() > DeclVersion)
>>>> -        DeclVersion = AA->getIntroduced();
>>>> -  }
>>>> -
>>>> -  return std::max(DeclVersion, 
>>>> Context.getTargetInfo().getPlatformMinVersion());
>>>> -}
>>>> -
>>>> namespace {
>>>> 
>>>> /// \brief This class implements -Wunguarded-availability.
>>>> @@ -6651,6 +6649,7 @@ class DiagnoseUnguardedAvailability
>>>>  typedef RecursiveASTVisitor<DiagnoseUnguardedAvailability> Base;
>>>> 
>>>>  Sema &SemaRef;
>>>> +  Decl *Ctx;
>>>> 
>>>>  /// Stack of potentially nested 'if (@available(...))'s.
>>>>  SmallVector<VersionTuple, 8> AvailabilityStack;
>>>> @@ -6658,9 +6657,10 @@ class DiagnoseUnguardedAvailability
>>>>  void DiagnoseDeclAvailability(NamedDecl *D, SourceRange Range);
>>>> 
>>>> public:
>>>> -  DiagnoseUnguardedAvailability(Sema &SemaRef, VersionTuple BaseVersion)
>>>> -      : SemaRef(SemaRef) {
>>>> -    AvailabilityStack.push_back(BaseVersion);
>>>> +  DiagnoseUnguardedAvailability(Sema &SemaRef, Decl *Ctx)
>>>> +      : SemaRef(SemaRef), Ctx(Ctx) {
>>>> +    AvailabilityStack.push_back(
>>>> +        SemaRef.Context.getTargetInfo().getPlatformMinVersion());
>>>>  }
>>>> 
>>>>  void IssueDiagnostics(Stmt *S) { TraverseStmt(S); }
>>>> @@ -6693,8 +6693,8 @@ void DiagnoseUnguardedAvailability::Diag
>>>>    NamedDecl *D, SourceRange Range) {
>>>> 
>>>>  VersionTuple ContextVersion = AvailabilityStack.back();
>>>> -  if (AvailabilityResult Result = 
>>>> SemaRef.ShouldDiagnoseAvailabilityOfDecl(
>>>> -          D, ContextVersion, nullptr)) {
>>>> +  if (AvailabilityResult Result =
>>>> +          SemaRef.ShouldDiagnoseAvailabilityOfDecl(D, nullptr)) {
>>>>    // All other diagnostic kinds have already been handled in
>>>>    // DiagnoseAvailabilityOfDecl.
>>>>    if (Result != AR_NotYetIntroduced)
>>>> @@ -6703,6 +6703,14 @@ void DiagnoseUnguardedAvailability::Diag
>>>>    const AvailabilityAttr *AA = 
>>>> getAttrForPlatform(SemaRef.getASTContext(), D);
>>>>    VersionTuple Introduced = AA->getIntroduced();
>>>> 
>>>> +    if (ContextVersion >= Introduced)
>>>> +      return;
>>>> +
>>>> +    // If the context of this function is less available than D, we 
>>>> should not
>>>> +    // emit a diagnostic.
>>>> +    if (!ShouldDiagnoseAvailabilityInContext(SemaRef, Result, Introduced, 
>>>> Ctx))
>>>> +      return;
>>>> +
>>>>    SemaRef.Diag(Range.getBegin(), diag::warn_unguarded_availability)
>>>>        << Range << D
>>>>        << AvailabilityAttr::getPrettyPlatformName(
>>>> @@ -6777,6 +6785,5 @@ void Sema::DiagnoseUnguardedAvailability
>>>> 
>>>>  assert(Body && "Need a body here!");
>>>> 
>>>> -  VersionTuple BaseVersion = getVersionForDecl(D);
>>>> -  DiagnoseUnguardedAvailability(*this, 
>>>> BaseVersion).IssueDiagnostics(Body);
>>>> +  DiagnoseUnguardedAvailability(*this, D).IssueDiagnostics(Body);
>>>> }
>>>> 
>>>> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
>>>> URL: 
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=284265&r1=284264&r2=284265&view=diff
>>>>  
>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=284265&r1=284264&r2=284265&view=diff>
>>>> ==============================================================================
>>>> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
>>>> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Oct 14 14:08:01 2016
>>>> @@ -103,9 +103,9 @@ static bool HasRedeclarationWithoutAvail
>>>>  return false;
>>>> }
>>>> 
>>>> -AvailabilityResult Sema::ShouldDiagnoseAvailabilityOfDecl(
>>>> -    NamedDecl *&D, VersionTuple ContextVersion, std::string *Message) {
>>>> -  AvailabilityResult Result = D->getAvailability(Message, ContextVersion);
>>>> +AvailabilityResult
>>>> +Sema::ShouldDiagnoseAvailabilityOfDecl(NamedDecl *&D, std::string 
>>>> *Message) {
>>>> +  AvailabilityResult Result = D->getAvailability(Message);
>>>> 
>>>>  // For typedefs, if the typedef declaration appears available look
>>>>  // to the underlying type to see if it is more restrictive.
>>>> @@ -113,7 +113,7 @@ AvailabilityResult Sema::ShouldDiagnoseA
>>>>    if (Result == AR_Available) {
>>>>      if (const TagType *TT = TD->getUnderlyingType()->getAs<TagType>()) {
>>>>        D = TT->getDecl();
>>>> -        Result = D->getAvailability(Message, ContextVersion);
>>>> +        Result = D->getAvailability(Message);
>>>>        continue;
>>>>      }
>>>>    }
>>>> @@ -124,7 +124,7 @@ AvailabilityResult Sema::ShouldDiagnoseA
>>>>  if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
>>>>    if (IDecl->getDefinition()) {
>>>>      D = IDecl->getDefinition();
>>>> -      Result = D->getAvailability(Message, ContextVersion);
>>>> +      Result = D->getAvailability(Message);
>>>>    }
>>>>  }
>>>> 
>>>> @@ -132,18 +132,10 @@ AvailabilityResult Sema::ShouldDiagnoseA
>>>>    if (Result == AR_Available) {
>>>>      const DeclContext *DC = ECD->getDeclContext();
>>>>      if (const EnumDecl *TheEnumDecl = dyn_cast<EnumDecl>(DC))
>>>> -        Result = TheEnumDecl->getAvailability(Message, ContextVersion);
>>>> +        Result = TheEnumDecl->getAvailability(Message);
>>>>    }
>>>> 
>>>> -  switch (Result) {
>>>> -  case AR_Available:
>>>> -    return Result;
>>>> -
>>>> -  case AR_Unavailable:
>>>> -  case AR_Deprecated:
>>>> -    return getCurContextAvailability() != Result ? Result : AR_Available;
>>>> -
>>>> -  case AR_NotYetIntroduced: {
>>>> +  if (Result == AR_NotYetIntroduced) {
>>>>    // Don't do this for enums, they can't be redeclared.
>>>>    if (isa<EnumConstantDecl>(D) || isa<EnumDecl>(D))
>>>>      return AR_Available;
>>>> @@ -166,23 +158,18 @@ AvailabilityResult Sema::ShouldDiagnoseA
>>>> 
>>>>    return Warn ? AR_NotYetIntroduced : AR_Available;
>>>>  }
>>>> -  }
>>>> -  llvm_unreachable("Unknown availability result!");
>>>> +
>>>> +  return Result;
>>>> }
>>>> 
>>>> static void
>>>> DiagnoseAvailabilityOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc,
>>>>                           const ObjCInterfaceDecl *UnknownObjCClass,
>>>>                           bool ObjCPropertyAccess) {
>>>> -  VersionTuple ContextVersion;
>>>> -  if (const DeclContext *DC = S.getCurObjCLexicalContext())
>>>> -    ContextVersion = S.getVersionForDecl(cast<Decl>(DC));
>>>> -
>>>>  std::string Message;
>>>> -  // See if this declaration is unavailable, deprecated, or partial in the
>>>> -  // current context.
>>>> +  // See if this declaration is unavailable, deprecated, or partial.
>>>>  if (AvailabilityResult Result =
>>>> -          S.ShouldDiagnoseAvailabilityOfDecl(D, ContextVersion, 
>>>> &Message)) {
>>>> +          S.ShouldDiagnoseAvailabilityOfDecl(D, &Message)) {
>>>> 
>>>>    if (Result == AR_NotYetIntroduced && S.getCurFunctionOrMethodDecl()) {
>>>>      S.getEnclosingFunction()->HasPotentialAvailabilityViolations = true;
>>>> @@ -192,8 +179,7 @@ DiagnoseAvailabilityOfDecl(Sema &S, Name
>>>>    const ObjCPropertyDecl *ObjCPDecl = nullptr;
>>>>    if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
>>>>      if (const ObjCPropertyDecl *PD = MD->findPropertyDecl()) {
>>>> -        AvailabilityResult PDeclResult =
>>>> -            PD->getAvailability(nullptr, ContextVersion);
>>>> +        AvailabilityResult PDeclResult = PD->getAvailability(nullptr);
>>>>        if (PDeclResult == Result)
>>>>          ObjCPDecl = PD;
>>>>      }
>>>> 
>>>> Modified: cfe/trunk/test/SemaObjC/class-unavail-warning.m
>>>> URL: 
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/class-unavail-warning.m?rev=284265&r1=284264&r2=284265&view=diff
>>>>  
>>>> <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/class-unavail-warning.m?rev=284265&r1=284264&r2=284265&view=diff>
>>>> ==============================================================================
>>>> --- cfe/trunk/test/SemaObjC/class-unavail-warning.m (original)
>>>> +++ cfe/trunk/test/SemaObjC/class-unavail-warning.m Fri Oct 14 14:08:01 
>>>> 2016
>>>> @@ -1,4 +1,4 @@
>>>> -// RUN: %clang_cc1  -fsyntax-only  -triple x86_64-apple-darwin10 -verify 
>>>> %s
>>>> +// RUN: %clang_cc1  -fsyntax-only -fblocks -triple x86_64-apple-darwin10 
>>>> -verify %s
>>>> // rdar://9092208 <rdar://9092208>
>>>> 
>>>> __attribute__((unavailable("not available")))
>>>> @@ -98,3 +98,19 @@ UNAVAILABLE
>>>> @end
>>>> @interface UnavailSub(cat)<SomeProto> // no error
>>>> @end
>>>> +
>>>> +int unavail_global UNAVAILABLE;
>>>> +
>>>> +UNAVAILABLE __attribute__((objc_root_class))
>>>> +@interface TestAttrContext
>>>> +-meth;
>>>> +@end
>>>> +
>>>> +@implementation TestAttrContext
>>>> +-meth {
>>>> +  unavail_global = 2; // no warn
>>>> +  (void) ^{
>>>> +    unavail_global = 4; // no warn
>>>> +  };
>>>> +}
>>>> +@end
>>>> 
>>>> 
>>>> _______________________________________________
>>>> cfe-commits mailing list
>>>> cfe-commits@lists.llvm.org <mailto:cfe-commits@lists.llvm.org>
>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits 
>>>> <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits>
>>> 
>> 
> 

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to