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:
Argyrios Kyrtzidis 2011-10-06 23:23:27 +00:00
parent 9321ad3f97
commit c281c96675
8 changed files with 40 additions and 8 deletions

View File

@ -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.

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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()) {

View File

@ -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();

View File

@ -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}}

View File

@ -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}}

View File

@ -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}}