mirror of https://github.com/microsoft/clang.git
[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:
parent
3f205d63b2
commit
094219decc
|
@ -644,9 +644,14 @@ public:
|
||||||
///
|
///
|
||||||
/// \param EnclosingVersion The version to compare with. If empty, assume the
|
/// \param EnclosingVersion The version to compare with. If empty, assume the
|
||||||
/// deployment target version.
|
/// 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
|
AvailabilityResult
|
||||||
getAvailability(std::string *Message = nullptr,
|
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
|
/// \brief Retrieve the version of the target platform in which this
|
||||||
/// declaration was introduced.
|
/// declaration was introduced.
|
||||||
|
|
|
@ -590,9 +590,11 @@ static AvailabilityResult CheckAvailability(ASTContext &Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
AvailabilityResult Decl::getAvailability(std::string *Message,
|
AvailabilityResult Decl::getAvailability(std::string *Message,
|
||||||
VersionTuple EnclosingVersion) const {
|
VersionTuple EnclosingVersion,
|
||||||
|
StringRef *RealizedPlatform) const {
|
||||||
if (auto *FTD = dyn_cast<FunctionTemplateDecl>(this))
|
if (auto *FTD = dyn_cast<FunctionTemplateDecl>(this))
|
||||||
return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion);
|
return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion,
|
||||||
|
RealizedPlatform);
|
||||||
|
|
||||||
AvailabilityResult Result = AR_Available;
|
AvailabilityResult Result = AR_Available;
|
||||||
std::string ResultMessage;
|
std::string ResultMessage;
|
||||||
|
@ -619,8 +621,11 @@ AvailabilityResult Decl::getAvailability(std::string *Message,
|
||||||
AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,
|
AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,
|
||||||
Message, EnclosingVersion);
|
Message, EnclosingVersion);
|
||||||
|
|
||||||
if (AR == AR_Unavailable)
|
if (AR == AR_Unavailable) {
|
||||||
|
if (RealizedPlatform)
|
||||||
|
*RealizedPlatform = Availability->getPlatform()->getName();
|
||||||
return AR_Unavailable;
|
return AR_Unavailable;
|
||||||
|
}
|
||||||
|
|
||||||
if (AR > Result) {
|
if (AR > Result) {
|
||||||
Result = AR;
|
Result = AR;
|
||||||
|
|
|
@ -266,12 +266,20 @@ static void DiagnoseObjCImplementedDeprecations(Sema &S, const NamedDecl *ND,
|
||||||
if (!ND)
|
if (!ND)
|
||||||
return;
|
return;
|
||||||
bool IsCategory = false;
|
bool IsCategory = false;
|
||||||
AvailabilityResult Availability = ND->getAvailability();
|
StringRef RealizedPlatform;
|
||||||
|
AvailabilityResult Availability = ND->getAvailability(
|
||||||
|
/*Message=*/nullptr, /*EnclosingVersion=*/VersionTuple(),
|
||||||
|
&RealizedPlatform);
|
||||||
if (Availability != AR_Deprecated) {
|
if (Availability != AR_Deprecated) {
|
||||||
if (isa<ObjCMethodDecl>(ND)) {
|
if (isa<ObjCMethodDecl>(ND)) {
|
||||||
if (Availability != AR_Unavailable)
|
if (Availability != AR_Unavailable)
|
||||||
return;
|
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(ImplLoc, diag::warn_unavailable_def);
|
||||||
S.Diag(ND->getLocation(), diag::note_method_declared_at)
|
S.Diag(ND->getLocation(), diag::note_method_declared_at)
|
||||||
<< ND->getDeclName();
|
<< ND->getDeclName();
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue