[ObjC] Supress the 'implementing unavailable method' warning when

the method declaration is unavailable for an app extension platform

Rationale:
Classes are often shared between an app extension code and
non-app extension code. There's no way to remove the implementation
using preprocessor when building the app extension, so we should not warn here.

rdar://38150617


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@331421 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Alex Lorenz 2018-05-03 01:12:06 +00:00
parent 3f205d63b2
commit 094219decc
4 changed files with 48 additions and 6 deletions

View File

@ -644,9 +644,14 @@ public:
///
/// \param EnclosingVersion The version to compare with. If empty, assume the
/// deployment target version.
///
/// \param RealizedPlatform If non-NULL and the availability result is found
/// in an available attribute it will set to the platform which is written in
/// the available attribute.
AvailabilityResult
getAvailability(std::string *Message = nullptr,
VersionTuple EnclosingVersion = VersionTuple()) const;
VersionTuple EnclosingVersion = VersionTuple(),
StringRef *RealizedPlatform = nullptr) const;
/// \brief Retrieve the version of the target platform in which this
/// declaration was introduced.

View File

@ -590,9 +590,11 @@ static AvailabilityResult CheckAvailability(ASTContext &Context,
}
AvailabilityResult Decl::getAvailability(std::string *Message,
VersionTuple EnclosingVersion) const {
VersionTuple EnclosingVersion,
StringRef *RealizedPlatform) const {
if (auto *FTD = dyn_cast<FunctionTemplateDecl>(this))
return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion);
return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion,
RealizedPlatform);
AvailabilityResult Result = AR_Available;
std::string ResultMessage;
@ -619,8 +621,11 @@ AvailabilityResult Decl::getAvailability(std::string *Message,
AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,
Message, EnclosingVersion);
if (AR == AR_Unavailable)
if (AR == AR_Unavailable) {
if (RealizedPlatform)
*RealizedPlatform = Availability->getPlatform()->getName();
return AR_Unavailable;
}
if (AR > Result) {
Result = AR;

View File

@ -266,12 +266,20 @@ static void DiagnoseObjCImplementedDeprecations(Sema &S, const NamedDecl *ND,
if (!ND)
return;
bool IsCategory = false;
AvailabilityResult Availability = ND->getAvailability();
StringRef RealizedPlatform;
AvailabilityResult Availability = ND->getAvailability(
/*Message=*/nullptr, /*EnclosingVersion=*/VersionTuple(),
&RealizedPlatform);
if (Availability != AR_Deprecated) {
if (isa<ObjCMethodDecl>(ND)) {
if (Availability != AR_Unavailable)
return;
// Warn about implementing unavailable methods.
if (RealizedPlatform.empty())
RealizedPlatform = S.Context.getTargetInfo().getPlatformName();
// Warn about implementing unavailable methods, unless the unavailable
// is for an app extension.
if (RealizedPlatform.endswith("_app_extension"))
return;
S.Diag(ImplLoc, diag::warn_unavailable_def);
S.Diag(ND->getLocation(), diag::note_method_declared_at)
<< ND->getDeclName();

View File

@ -0,0 +1,24 @@
// RUN: %clang_cc1 -triple arm64-apple-ios11 -fapplication-extension -Wdeprecated-implementations -verify -Wno-objc-root-class %s
// RUN: %clang_cc1 -triple arm64-apple-tvos11 -fapplication-extension -Wdeprecated-implementations -verify -Wno-objc-root-class %s
// Declarations marked as 'unavailable' in an app extension should not generate a
// warning on implementation.
@interface Parent
- (void)ok __attribute__((availability(ios_app_extension,unavailable,message="not available")));
- (void)reallyUnavail __attribute__((availability(ios,unavailable))); // expected-note {{method 'reallyUnavail' declared here}}
- (void)reallyUnavail2 __attribute__((unavailable)); // expected-note {{method 'reallyUnavail2' declared here}}
@end
@interface Child : Parent
@end
@implementation Child
- (void)ok { // no warning.
}
- (void)reallyUnavail { // expected-warning {{implementing unavailable method}}
}
- (void)reallyUnavail2 { // expected-warning {{implementing unavailable method}}
}
@end