DeclContext *getCurLexicalContext() const {
return OriginalLexicalContext ? OriginalLexicalContext : CurContext;
}
+
+ AvailabilityResult getCurContextAvailability() const;
};
/// \brief RAII object that enters a new expression evaluation context.
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();
+}
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;
}
// 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);
// 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()) {
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();
@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}}
// 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.
- (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}}
@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}}