objective-c: Ignore with warning forward class declaration whose name
matches a typedef declaring an object type. // rdar://10733000 llvm-svn: 148760
This commit is contained in:
parent
ed975232bc
commit
04c4455dd4
|
@ -2809,6 +2809,9 @@ def err_redefinition_different_type : Error<
|
|||
"redefinition of %0 with a different type">;
|
||||
def err_redefinition_different_kind : Error<
|
||||
"redefinition of %0 as different kind of symbol">;
|
||||
def warn_forward_class_redefinition : Warning<
|
||||
"redefinition of forward class %0 of a typedef name of an object type is ignored">,
|
||||
InGroup<DiagGroup<"objc-forward-class-redefinition">>;
|
||||
def err_redefinition_different_typedef : Error<
|
||||
"%select{typedef|type alias|type alias template}0 redefinition with different types (%1 vs %2)">;
|
||||
def err_tag_reference_non_tag : Error<
|
||||
|
|
|
@ -1776,17 +1776,22 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
|
|||
// typedef NSObject < XCElementTogglerP > XCElementToggler;
|
||||
// @class XCElementToggler;
|
||||
//
|
||||
// FIXME: Make an extension?
|
||||
// Here we have chosen to ignore the forward class declaration
|
||||
// with a warning. Since this is the implied behavior.
|
||||
TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(PrevDecl);
|
||||
if (!TDD || !TDD->getUnderlyingType()->isObjCObjectType()) {
|
||||
Diag(AtClassLoc, diag::err_redefinition_different_kind) << IdentList[i];
|
||||
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
|
||||
} else {
|
||||
// a forward class declaration matching a typedef name of a class refers
|
||||
// to the underlying class.
|
||||
if (const ObjCObjectType *OI =
|
||||
TDD->getUnderlyingType()->getAs<ObjCObjectType>())
|
||||
PrevDecl = OI->getInterface();
|
||||
// to the underlying class. Just ignore the forward class with a warning
|
||||
// as this will force the intended behavior which is to lookup the typedef
|
||||
// name.
|
||||
if (isa<ObjCObjectType>(TDD->getUnderlyingType())) {
|
||||
Diag(AtClassLoc, diag::warn_forward_class_redefinition) << IdentList[i];
|
||||
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
|
||||
@protocol XCElementP @end
|
||||
|
||||
typedef NSObject <XCElementP> XCElement;
|
||||
typedef NSObject <XCElementP> XCElement; // expected-note {{previous definition is here}}
|
||||
|
||||
@interface XCElementMainImp {
|
||||
XCElement * _editingElement;
|
||||
}
|
||||
@end
|
||||
|
||||
@class XCElement;
|
||||
@class XCElement; // expected-warning {{redefinition of forward class 'XCElement' of a typedef name of an object type is ignored}}
|
||||
|
||||
@implementation XCElementMainImp
|
||||
- (XCElement *)editingElement { return _editingElement; }
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
// rdar://10733000
|
||||
|
||||
@interface NSObject @end
|
||||
|
||||
@protocol PLAssetContainer
|
||||
@property (readonly, nonatomic, retain) id assets;
|
||||
@end
|
||||
|
||||
|
||||
typedef NSObject <PLAssetContainer> PLAlbum; // expected-note {{previous definition is here}}
|
||||
|
||||
@class PLAlbum; // expected-warning {{redefinition of forward class 'PLAlbum' of a typedef name of an object type is ignore}}
|
||||
|
||||
@interface PLPhotoBrowserController
|
||||
{
|
||||
PLAlbum *_album;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface WPhotoViewController:PLPhotoBrowserController
|
||||
@end
|
||||
|
||||
@implementation WPhotoViewController
|
||||
- (void)_prepareForContracting
|
||||
{
|
||||
(void)_album.assets;
|
||||
}
|
||||
@end
|
|
@ -48,13 +48,13 @@ typedef NSObject < XCElementSpacerP > XCElementSpacer;
|
|||
@protocol XCElementTogglerP < XCElementP > -(void) setDisplayed:(BOOL) displayed;
|
||||
@end
|
||||
|
||||
typedef NSObject < XCElementTogglerP > XCElementToggler;
|
||||
typedef NSObject < XCElementTogglerP > XCElementToggler; // expected-note {{previous definition is here}}
|
||||
|
||||
@interface XCElementRootFace:NSObject {} @end
|
||||
|
||||
@interface XCElementFace:XCElementRootFace {} @end
|
||||
|
||||
@class XCElementToggler;
|
||||
@class XCElementToggler; // expected-warning {{redefinition of forward class 'XCElementToggler' of a typedef name of an object type is ignored}}
|
||||
|
||||
@interface XCRASlice:XCElementFace {} @end
|
||||
|
||||
|
|
Loading…
Reference in New Issue