objc: When issue diagnostic about deprecated method, also

issue the note if it is because message is sent to a forward class
declaration in delayed diagnostic. // rdar://10290322

llvm-svn: 151942
This commit is contained in:
Fariborz Jahanian 2012-03-02 21:50:02 +00:00
parent a748664c9d
commit 7923ef41e1
4 changed files with 44 additions and 5 deletions

View File

@ -122,8 +122,9 @@ public:
void Destroy();
static DelayedDiagnostic makeDeprecation(SourceLocation Loc,
const NamedDecl *D,
StringRef Msg);
const NamedDecl *D,
const ObjCInterfaceDecl *UnknownObjCClass,
StringRef Msg);
static DelayedDiagnostic makeAccess(SourceLocation Loc,
const AccessedEntity &Entity) {
@ -187,12 +188,17 @@ public:
assert(Kind == ForbiddenType && "not a forbidden-type diagnostic");
return QualType::getFromOpaquePtr(ForbiddenTypeData.OperandType);
}
const ObjCInterfaceDecl *getUnknownObjCClass() const {
return DeprecationData.UnknownObjCClass;
}
private:
union {
/// Deprecation.
struct {
const NamedDecl *Decl;
const ObjCInterfaceDecl *UnknownObjCClass;
const char *Message;
size_t MessageLen;
} DeprecationData;

View File

@ -20,13 +20,15 @@ using namespace clang;
using namespace sema;
DelayedDiagnostic DelayedDiagnostic::makeDeprecation(SourceLocation Loc,
const NamedDecl *D,
StringRef Msg) {
const NamedDecl *D,
const ObjCInterfaceDecl *UnknownObjCClass,
StringRef Msg) {
DelayedDiagnostic DD;
DD.Kind = Deprecation;
DD.Triggered = false;
DD.Loc = Loc;
DD.DeprecationData.Decl = D;
DD.DeprecationData.UnknownObjCClass = UnknownObjCClass;
char *MessageData = 0;
if (Msg.size()) {
MessageData = new char [Msg.size()];

View File

@ -4121,6 +4121,11 @@ void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
Diag(DD.Loc, diag::warn_deprecated_message)
<< DD.getDeprecationDecl()->getDeclName()
<< DD.getDeprecationMessage();
else if (DD.getUnknownObjCClass()) {
Diag(DD.Loc, diag::warn_deprecated_fwdclass_message)
<< DD.getDeprecationDecl()->getDeclName();
Diag(DD.getUnknownObjCClass()->getLocation(), diag::note_forward_class);
}
else
Diag(DD.Loc, diag::warn_deprecated)
<< DD.getDeprecationDecl()->getDeclName();
@ -4131,7 +4136,9 @@ void Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
const ObjCInterfaceDecl *UnknownObjCClass) {
// Delay if we're currently parsing a declaration.
if (DelayedDiagnostics.shouldDelayDiagnostics()) {
DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, Message));
DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D,
UnknownObjCClass,
Message));
return;
}

View File

@ -0,0 +1,24 @@
// RUN: %clang_cc1 %s -fsyntax-only -verify
// rdar://10290322
@class ABGroupImportFilesScope; // expected-note {{forward declaration of class here}}
@interface I1
- (id) filenames __attribute__((deprecated));
@end
@interface I2
- (id) Meth : (ABGroupImportFilesScope*) scope;
- (id) filenames __attribute__((deprecated));
- (id)initWithAccount: (id)account filenames:(id)filenames;
@end
@implementation I2
- (id) Meth : (ABGroupImportFilesScope*) scope
{
id p = [self initWithAccount : 0 filenames :[scope filenames]]; // expected-warning {{'filenames' maybe deprecated because receiver type is unknown}}
return 0;
}
- (id) filenames { return 0; }
- (id)initWithAccount: (id)account filenames:(id)filenames { return 0; }
@end