"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<
// 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;
+ }
}
}
@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; }
--- /dev/null
+// 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
@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