Implicitly assume that a ObjC category to an unavailable interface is also unavailable;
only give an 'unavailable' error on the @implementation of the category. rdar://10234078 llvm-svn: 141335
This commit is contained in:
parent
9321ad3f97
commit
c281c96675
|
@ -6165,6 +6165,8 @@ public:
|
|||
DeclContext *getCurLexicalContext() const {
|
||||
return OriginalLexicalContext ? OriginalLexicalContext : CurContext;
|
||||
}
|
||||
|
||||
AvailabilityResult getCurContextAvailability() const;
|
||||
};
|
||||
|
||||
/// \brief RAII object that enters a new expression evaluation context.
|
||||
|
|
|
@ -9663,3 +9663,12 @@ void Sema::ActOnPragmaWeakAlias(IdentifierInfo* Name,
|
|||
Decl *Sema::getObjCDeclContext() const {
|
||||
return (dyn_cast_or_null<ObjCContainerDecl>(CurContext));
|
||||
}
|
||||
|
||||
AvailabilityResult Sema::getCurContextAvailability() const {
|
||||
const Decl *D = cast<Decl>(getCurLexicalContext());
|
||||
// A category implicitly has the availability of the interface.
|
||||
if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
|
||||
D = CatD->getClassInterface();
|
||||
|
||||
return D->getAvailability();
|
||||
}
|
||||
|
|
|
@ -4002,6 +4002,9 @@ 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))
|
||||
return CatD->getClassInterface()->isDeprecated();
|
||||
} while ((D = cast_or_null<Decl>(D->getDeclContext())));
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -770,9 +770,6 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
|
|||
// FIXME: PushOnScopeChains?
|
||||
CurContext->addDecl(CDecl);
|
||||
|
||||
// If the interface is deprecated, warn about it.
|
||||
(void)DiagnoseUseOfDecl(IDecl, ClassLoc);
|
||||
|
||||
if (NumProtoRefs) {
|
||||
CDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,
|
||||
ProtoLocs, Context);
|
||||
|
@ -818,6 +815,10 @@ Decl *Sema::ActOnStartCategoryImplementation(
|
|||
// FIXME: PushOnScopeChains?
|
||||
CurContext->addDecl(CDecl);
|
||||
|
||||
// If the interface is deprecated/unavailable, warn/error about it.
|
||||
if (IDecl)
|
||||
DiagnoseUseOfDecl(IDecl, ClassLoc);
|
||||
|
||||
/// Check that CatName, category name, is not used in another implementation.
|
||||
if (CatIDecl) {
|
||||
if (CatIDecl->getImplementation()) {
|
||||
|
|
|
@ -72,8 +72,7 @@ static AvailabilityResult DiagnoseAvailabilityOfDecl(Sema &S,
|
|||
break;
|
||||
|
||||
case AR_Unavailable:
|
||||
if (cast<Decl>(S.getCurLexicalContext())->getAvailability() !=
|
||||
AR_Unavailable) {
|
||||
if (S.getCurContextAvailability() != AR_Unavailable) {
|
||||
if (Message.empty()) {
|
||||
if (!UnknownObjCClass)
|
||||
S.Diag(Loc, diag::err_unavailable) << D->getDeclName();
|
||||
|
|
|
@ -92,7 +92,14 @@ __attribute ((deprecated))
|
|||
@property int prop;
|
||||
@end
|
||||
|
||||
@interface DEPRECATED (Category) // expected-warning {{warning: 'DEPRECATED' is deprecated}}
|
||||
@interface DEPRECATED (Category) // no warning.
|
||||
- (DEPRECATED *) meth2; // no warning.
|
||||
@end
|
||||
|
||||
@interface DEPRECATED (Category2) // no warning.
|
||||
@end
|
||||
|
||||
@implementation DEPRECATED (Category2) // expected-warning {{warning: 'DEPRECATED' is deprecated}}
|
||||
@end
|
||||
|
||||
@interface NS : DEPRECATED // expected-warning {{warning: 'DEPRECATED' is deprecated}}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// rdar://9092208
|
||||
|
||||
__attribute__((unavailable("not available")))
|
||||
@interface MyClass { // expected-note 7 {{declaration has been explicitly marked unavailable here}}
|
||||
@interface MyClass { // expected-note 8 {{declaration has been explicitly marked unavailable here}}
|
||||
@public
|
||||
void *_test;
|
||||
MyClass *ivar; // no error.
|
||||
|
@ -21,6 +21,16 @@ __attribute__((unavailable("not available")))
|
|||
- (MyClass *)meth; // expected-error {{unavailable}}
|
||||
@end
|
||||
|
||||
@interface MyClass (Cat1)
|
||||
- (MyClass *)meth; // no error.
|
||||
@end
|
||||
|
||||
@interface MyClass (Cat2) // no error.
|
||||
@end
|
||||
|
||||
@implementation MyClass (Cat2) // expected-error {{unavailable}}
|
||||
@end
|
||||
|
||||
int main() {
|
||||
[MyClass new]; // expected-error {{'MyClass' is unavailable: not available}}
|
||||
[MyClass self]; // expected-error {{'MyClass' is unavailable: not available}}
|
||||
|
|
|
@ -26,7 +26,8 @@ __attribute__((deprecated))
|
|||
@implementation CL // expected-warning {{Implementing deprecated class}}
|
||||
@end
|
||||
|
||||
@implementation CL ( SomeCategory ) // expected-warning {{Implementing deprecated category}}
|
||||
@implementation CL ( SomeCategory ) // expected-warning {{'CL' is deprecated}} \
|
||||
// expected-warning {{Implementing deprecated category}}
|
||||
@end
|
||||
|
||||
@interface CL_SUB : CL // expected-warning {{'CL' is deprecated}}
|
||||
|
|
Loading…
Reference in New Issue